
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/lib.js
*/
// Copyright Wall Street On Demand
// JSJuiced using http://labs.gueschla.com/jsjuicer/, http://adrian3.googlepages.com/jsjuicer.html
// ------------------------------------------------------------------------------------------------
// slimmed down Function methods from wsdom.js
Function.prototype.Extend=function(superClass){this.prototype=new superClass();this.prototype.getSuperClass=function(){return superClass;};this.getSuperClass=this.prototype.getSuperClass;return this;};
Function.prototype.Super=function(context,methodName,args){if(null!=methodName){var method=this.getSuperClass().prototype[methodName];}
else{var method=this.getSuperClass();}
if(!args){return method.call(context);}
else{return method.apply(context,args);}};
Function.prototype.Context=function(obj){var fnReference=this;return function(){return typeof fnReference=="function"?fnReference.apply(obj,arguments):obj[fnReference].apply(obj,arguments);};};

// slimmed down Element.3.js
var Element_class=function(){}
Element_class.prototype.get=function(el){if(typeof el=="string")el=document.getElementById(el);return el;};Element_class.prototype.create=function(tag,attributes,children,parent,ElementObjectInstance){var element=document.createElement(tag);var attributeMap={"for":["htmlFor"],"colspan":["colSpan"]}
for(var i in attributes)
{if(i=="className"||i=="class")
{element.className=attributes[i];}
else if(document.all&&attributeMap[i])
{for(var j=0;j<attributeMap[i].length;j++){element.setAttribute(attributeMap[i][j],attributes[i]);}
element.setAttribute(i,attributes[i]);}
else if(i=="style")
{this.setStyle(element,attributes[i]);}
else if(i=="Events")
{if(typeof Events!="undefined"){var elEvents=attributes[i];if(!this.isArray(elEvents)){elEvents=[elEvents]}
for(var j=0;j<elEvents.length;j++){elEvents[j].element=element;Events.add(elEvents[j]);}}
else{alert(":: DEV ERROR :: \n Location: Element.3.js -- Element_class.prototype.create \n Type: Dependency \n Message: Expecting Events Lib for use of Events in Element.create")}}
else
{element.setAttribute(i,attributes[i]);};};if(arguments.length>2&&children)
{if(typeof children=="object"&&children.constructor==Array)
{for(var i=0;i<children.length;i++)
{this.addChild(element,children[i]);};}
else
{this.addChild(element,children);};};if(parent){this.addChild(parent,element);}
return(ElementObjectInstance)?new ElementObject(element):element;};Element_class.prototype.addChild=function(el,child){if(typeof child=="object")
{el.appendChild(child);}
else if(typeof child=="string"||typeof child=="number")
{el.innerHTML+=child;};};Element_class.prototype.remove=function(el){el=this.get(el);if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].parentNode.removeChild(el[i])}};Element_class.prototype.removeChildNodes=function(el){el=this.get(el);while(el.childNodes.length){el.removeChild(el.firstChild);}
return el;};Element_class.prototype.cloneNode=function(el,cloneChildren){var cloneChildNodes=(cloneChildren)?cloneChildren:false;if(document.all){var node=el.outerHTML;if(cloneChildNodes&&el.innerHTML){node.innerHTML=el.innerHTML;}
var container=document.createElement("DIV");container.innerHTML=node;node=container.firstChild;}else{var node=el.cloneNode(cloneChildNodes);}
return node;};Element_class.prototype.getParent=function(el,tag,includeSelf){var el=Element.get(el);if(!tag){tag=el.tagName;}
if(!includeSelf&&el.parentNode){el=el.parentNode;}
if(el.tagName&&el.tagName.match(/body/i)&&!tag.match(/body/i)){return null;}
if(el.nodeType==1&&el.tagName.toLowerCase()==tag.toLowerCase()){return el;}
else{return this.getParent(el.parentNode,tag,true);}}
Element_class.prototype.setAttribute=function(el,prop,val){el=this.get(el);if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].setAttribute(prop,val);}};Element_class.prototype.setHTML=function(el,v,appendV){el=this.get(el);if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].innerHTML=(appendV)?(el[i].innerHTML+v):v;}};
/* parseselector */
Element_class.prototype.parseSelector=function(){var context=this;var SEPERATOR=/\s*,\s*/;function parseSelector(selector,node,num){node=node||document.documentElement;node=this.get(node);var argSelectors=selector.split(SEPERATOR);var result=[];for(var i=0;i<argSelectors.length;i++){if(node==document.documentElement){var matches=argSelectors[i].match(/^\s*#([^\s.:@[~+>]*)\s+(.*)$/);if(matches){node=document.getElementById(matches[1])||[];argSelectors[i]=matches[2];}}
var stream=toStream(argSelectors[i]),prevToken;if(this.isArray(node)){var nodes=node;if(!argSelectors[i].match(/^[A-Za-z1-9]/)){while(stream[0]&&stream[0].match(/[* ]/)){stream.shift();}}}
else{var nodes=[node]}
for(var j=0;j<stream.length;){var token=stream[j++];var args='';if(token=="["){args=stream[j];while(stream[j++]!=']'&&j<stream.length){args+=stream[j]};args=args.slice(0,-1);var filter="";}
else{var filter=stream[j++];}
if(stream[j]=='('){while(stream[j++]!=')'&&j<stream.length)args+=stream[j];args=args.slice(0,-1);}
prevToken=token;nodes=select(nodes,token,filter,args);}
result=result.concat(nodes);}
if(num!=undefined){if(result.length){var REMatch;if(num=="first"){return result[0]}
else if(num=="last"){return result[result.length-1]}
else if(REMatch=String(num).match(/nth\((.*)\)/)||num=="even"){if(num=="even")num=2;else num=REMatch[1];var result2=[];for(var i=0,len=result.length;i<len;i++){if(i%num==0){result2.push(result[i]);}}
return result2;}
else if(num=="odd"){var result2=[];for(var i=0,len=result.length;i<len;i++){if(i%2!=0){result2.push(result[i]);}}
return result2;}
else if(!isNaN(num)&&result.length>=num){return result[num]}
else{return null;}}
else{return null;}}
return result;}
var WHITESPACE=/\s*([\s>+~(),]|^|$)\s*/g;var IMPLIED_ALL=/([\s>+~,]|[^(]\+|^)([#.:@])/g;var STANDARD_SELECT=/^[^\s>+~]/;var STREAM=/[\s#.:>+~[\]()@!]|[^\s#.:>+~[\]()@!]+/g;function toStream(selector){var stream=selector.replace(WHITESPACE,'$1').replace(IMPLIED_ALL,'$1*$2');if(STANDARD_SELECT.test(stream)){stream=' '+stream;}
return stream.match(STREAM)||[];}
function select(nodes,token,filter,args){return(selectors[token])?selectors[token](nodes,filter,args):[];}
var util={toArray:function(enumerable){var a=[];for(var i=0;i<enumerable.length;i++)a.push(enumerable[i]);return a;},push:function(arr,val){arr.push(val)
return arr.length;}};var dom={isTag:function(node,tag){return(tag=='*')||(tag.toLowerCase()==node.nodeName.toLowerCase().replace(':html',''));},previousSiblingElement:function(node){do node=node.previousSibling;while(node&&node.nodeType!=1);return node;},nextSiblingElement:function(node){do node=node.nextSibling;while(node&&node.nodeType!=1);return node;},hasClass:function(name,node){return(node.className||'').match('(^|\\s)'+name+'(\\s|$)');},getByTag:function(tag,node){if(tag=='*'){var nodes=node.getElementsByTagName(tag);if(nodes.length==0&&node.all!=null)return node.all
return nodes;}
return node.getElementsByTagName(tag);}};var selectors={'#':function(nodes,filter){for(var i=0;i<nodes.length;i++){if(nodes[i].getAttribute('id')==filter)return[nodes[i]];}
return[];},' ':function(nodes,filter){var result=[];for(var i=0;i<nodes.length;i++){result=result.concat(util.toArray(dom.getByTag(filter,nodes[i])));}
return result;},'>':function(nodes,filter){var result=[];for(var i=0,node;i<nodes.length;i++){node=nodes[i];for(var j=0,child;j<node.childNodes.length;j++){child=node.childNodes[j];if(child.nodeType==1&&dom.isTag(child,filter)){result.push(child);}}}
return result;},'.':function(nodes,filter){var result=[];for(var i=0,node;i<nodes.length;i++){node=nodes[i];if(dom.hasClass([filter],node))result.push(node);}
return result;},'!':function(nodes,filter){var result=[];for(var i=0,node;i<nodes.length;i++){node=nodes[i];if(!dom.hasClass([filter],node))result.push(node);}
return result;},':':function(nodes,filter,args){return(pseudoClasses[filter])?pseudoClasses[filter](nodes,args):[];},'+':function(nodes,filter){var result=[];for(var i=0,node;i<nodes.length;i++){node=nodes[i];var sibling=parseSelector.dom.nextSiblingElement(node);if(sibling&&parseSelector.dom.isTag(sibling,filter)){result.push(sibling);}}
return result;},'~':function(nodes,filter){var result=[];for(var i=0,node;i<nodes.length;i++){node=nodes[i];var sibling=parseSelector.dom.previousSiblingElement(node);if(parseSelector.dom.isTag(sibling,filter))result.push(sibling);}
return result;},'[':function(nodes,filter,args){args=args.replace(/'/g,'"');var attributeProps=[];if(!/[<>=]/.test(args)){attributeProps=["",args,"",""];}
else{var params=args.match(/([^!^$*\/.<>=]*)(!\*=|\*=|\$=|!\$=|\^=|\/=|!\/=|<=|>=|<|>|!=|=)(\.*)(i?)(["'`])([^\5]*)(\5)/);if(params){attributeProps=params;}}
attributeProps={name:attributeProps[1],operator:attributeProps[2],isStyle:attributeProps[3]=="..",isProperty:attributeProps[3]==".",casei:attributeProps[4]?true:false,value:attributeProps[6],isValue:(attributeProps[5]=="`")};if(attributeProps.casei){attributeProps.value=attributeProps.value.toLowerCase();}
var result=[];for(var i=0,node,att,val,el;i<nodes.length;i++){node=el=nodes[i];if(attributeProps.isStyle){att=context.getStyle(node,attributeProps.name);if(!att)continue;}
else if(attributeProps.isProperty){if(node[attributeProps.name]!=undefined){var att=node[attributeProps.name];}
else{continue;}}
else{att=node.getAttribute(attributeProps.name);if(!att)continue;}
if(/[*^$\/]/.test(attributeProps.operator)){att=String(att)}
if(attributeProps.casei){att=att.toLowerCase();}
val=attributeProps.value;if(attributeProps.isValue){val=eval(val.replace(/`/g,"'"));}
if(!attributeProps.operator){result.push(nodes[i])}
else{switch(attributeProps.operator){case'=':if(att==val)result.push(node);break;case'!=':if(att!=val)result.push(node);break;case'*=':if(att.match(val))result.push(node);break;case'!*=':if(!att.match(val))result.push(node);break;case'^=':if(att.match('^'+val))result.push(node);break;case'!^=':if(!att.match('^'+val))result.push(node);break;case'$=':if(att.match(val+'$'))result.push(node);break;case'!$=':if(!att.match(val+'$'))result.push(node);break;case'/=':if(att.match(val))result.push(node);break;case'!/=':if(!att.match(val))result.push(node);break;case'>=':if(att>=val)result.push(node);break;case'>':if(att>val)result.push(node);break;case'<=':if(att<=val)result.push(node);break;case'<':if(att<val)result.push(node);break;}}}
return result;}};parseSelector.selectors=selectors;var pseudoClasses={};parseSelector.pseudoClasses=pseudoClasses;parseSelector.util=util;parseSelector.dom=dom;return parseSelector.apply(this,arguments);};/* end parseselector */
Element_class.prototype.getParent=function(el,tag,includeSelf){var el=Element.get(el);if(!tag){tag=el.tagName;}
if(!includeSelf&&el.parentNode){el=el.parentNode;}
if(el.tagName&&el.tagName.match(/^BODY$/i)&&!tag.match(/^BODY$/i)){return null;}
if(el.nodeType==1&&el.tagName.toLowerCase()==tag.toLowerCase()){return el;}
else{return this.getParent(el.parentNode,tag,true);}}
Element_class.prototype.getParentBySelector=function(el,selector,includeSelf){el=this.get(el);var pNode=includeSelf?el:el.parentNode;selector=selector.replace(/\s+/," ").split(" ");var levels=selector.length;var level=0;var selectorType,isMatch,isTag,isClass;function getSelectorType(){var sel=selector[level];selectorType={tag:sel};if(sel.match(/(\D*)\#(\D*)/)){selectorType.tag=RegExp.$1;selectorType.id=RegExp.$2;}
else if(sel.match(/(.*)\[([^^$*]*?)((\*=|\$=|\^=|=)+["'](.*)["'])?]/)){selectorType.tag=RegExp.$1;selectorType.attribute=RegExp.$2;selectorType.operator=RegExp.$4;selectorType.value=RegExp.$5;}
else if(sel.match(/(\D*)\.(\D*)/)){selectorType.tag=RegExp.$1;selectorType.className=RegExp.$2;}}
getSelectorType();while(pNode&&!pNode.tagName.match(/^BODY$/i)){isMatch=false;isTag=pNode.tagName.match(new RegExp("^"+selectorType.tag.replace(/([*])/,"\\$1")+"$","i"))||selectorType.tag=="*"||selectorType.tag=="";isClass=selectorType.className&&this.hasClass(pNode,selectorType.className);if(isTag&&selectorType.attribute){var att=pNode.getAttribute(selectorType.attribute);if(!selectorType.operator){if(att)isMatch=true;}
else{switch(selectorType.operator){case'*=':;if(att.match(selectorType.value))isMatch=true;break;case'=':if(att==selectorType.value)isMatch=true;break;case'^=':if(att.match('^'+selectorType.value))isMatch=true;break;case'$=':if(att.match(selectorType.value+'$'))isMatch=true;}}}
else if(isTag){if(isClass){isMatch=true;}
else if(selectorType.tag&&!selectorType.className){isMatch=true;}
else if(selectorType.id&&pNode.getAttribute("id")==selectorType.id){isMatch=true;}}
else if(isTag&&isClass){isMatch=true;}
if(isMatch){if(level==levels-1){return pNode;}
level++;getSelectorType();}
pNode=pNode.parentNode||null;}
return null;}
Element_class.prototype.getSizeXY=function(el){var size=this.getSize(el);return{x:size.width,y:size.height};};
Element_class.prototype.setDisplay=function(el,d){el=this.get(el);if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].style.display=d;}};
Element_class.prototype.setVisibility=function(el,d){el=this.get(el);if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].style.visibility=d;}};

Element_class.prototype.insertBefore=function(el,sibling){el=this.get(el);if(!el)return;sibling=this.get(sibling);if(!el||!sibling||!sibling.parentNode)
{return null;};sibling.parentNode.insertBefore(el,sibling);};Element_class.prototype.insertAfter=function(el,sibling){el=this.get(el);if(!el)return;sibling=this.get(sibling);if(!el||!sibling||!sibling.parentNode)
{return null;};return sibling.nextSibling?sibling.parentNode.insertBefore(el,sibling.nextSibling):sibling.parentNode.appendChild(el);};Element_class.prototype.getXY=function(el){el=this.get(el);if(!el)return;var x=0,y=0;while(el.offsetParent){x+=el.offsetLeft;y+=el.offsetTop;el=el.offsetParent;}
return{x:x,y:y};};Element_class.prototype.setXY=function(el,x,y){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){if(x!==null)el[i].style.left=x+"px";if(y!==null)el[i].style.top=y+"px";}};Element_class.prototype.getSize=function(el){el=this.get(el);if(!el)return;var height=el.offsetHeight;var width=el.offsetWidth;return{height:height,width:width};};Element_class.prototype.setSize=function(el,width,height){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){this.setWidth(el[i],width);this.setHeight(el[i],height);}};Element_class.prototype.setWidth=function(el,width){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].style.width=width+"px";}};Element_class.prototype.setHeight=function(el,height){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].style.height=height+"px";}};Element_class.prototype.getBorderSize=function(el){el=this.get(el);var height=el.offsetHeight-el.clientHeight;var width=el.offsetWidth-el.clientWidth;return{height:height,width:width};};Element_class.prototype.setOpacity=function(el,opacity){el=this.get(el);if(!el)return
if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){el[i].style.filter="alpha(opacity:"+opacity+")";el[i].style.KHTMLOpacity=opacity/100;el[i].style.MozOpacity=opacity/100;el[i].style.opacity=opacity/100;}};Element_class.prototype.switchClass=function(el,classname,b){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
if(b){this.addClass(el,classname);}
else{this.removeClass(el,classname);}
if(el.length){return el[0].className;}};Element_class.prototype.replaceClass=function(el,oClassname,nClassname){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
this.removeClass(el,oClassname);this.addClass(el,nClassname);if(el.length){return el[0].className;}};Element_class.prototype.addClass=function(el,classname){el=this.get(el);if(!el)return;if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){if(!this.hasClass(el[i],classname)){el[i].className+=(el[i].className?" ":"")+classname;}}
if(el.length){return el[0].className;}};Element_class.prototype.removeClass=function(el,classname){el=this.get(el);if(!this.isArray(el)){el=[el]}
var re=this._getClassnameRegEx(classname);for(var i=0;i<el.length;i++){el[i].className=el[i].className.replace(re,"$1$3");}
if(el.length){return el[0].className;}};Element_class.prototype.toggleClass=function(el,classname){el=this.get(el);if(!this.isArray(el)){el=[el]}
for(var i=0;i<el.length;i++){if(this.hasClass(el[i],classname)){this.removeClass(el[i],classname);}else{this.addClass(el[i],classname);}}
if(el.length){return el[0].className;}};Element_class.prototype.hasClass=function(el,classname){el=this.get(el);return(el.className&&el.className.match(this._getClassnameRegEx(classname))!=null);};Element_class.prototype._getClassnameRegEx=function(classname){return new RegExp("(\\s|^)("+classname+")(\\s|$)","g")};Element_class.prototype.isArray=function(o){return(o instanceof Array);};Element=new Element_class();
Element_class.prototype.setStyle=function(el,styles){el=this.get(el);if(!el)return;var pairs=[];styles=styles.split(";");for(var i=0;i<styles.length;i++){var nv=styles[i].replace(":","{:}").split("{:}");if(nv.length>1){nv[0]=nv[0].replace(/\-(.)/g,function(){return arguments[1].toUpperCase();}).replace(/\s/g,"");pairs.push({n:nv[0],v:nv[1].replace(/^\s*|\s*$/g,"")});}}
if(!this.isArray(el)){el=[el]}
var attributeMap={"float":["cssFloat","styleFloat"]}
for(var i=0;i<el.length;i++){for(var j=0;j<pairs.length;j++){if(attributeMap[pairs[j].n]){for(var k=0;k<attributeMap[pairs[j].n].length;k++){pairs.push({n:attributeMap[pairs[j].n][k],v:pairs[j].v});}}
el[i].style[pairs[j].n]=pairs[j].v;}}}
/* thanks to PPK - http://www.quirksmode.org/viewport/compatibility.html */
Element_class.prototype.getWindowSize=function(){if(self.innerHeight){var width=self.innerWidth;var height=self.innerHeight;}else if(document.documentElement&&document.documentElement.clientHeight){var width=document.documentElement.clientWidth;var height=document.documentElement.clientHeight;}else if(document.body){var width=document.body.clientWidth;var height=document.body.clientHeight;};return{width:width,height:height};};Element_class.prototype.getWindowScrollOffset=function(){if(typeof window.pageYOffset=='number'){var x=window.pageXOffset;var y=window.pageYOffset;}else if(document.body&&(document.body.scrollLeft||document.body.scrollTop)){var x=document.body.scrollLeft;var y=document.body.scrollTop;}else if(document.documentElement&&(document.documentElement.scrollLeft||document.documentElement.scrollTop)){var x=document.documentElement.scrollLeft;var y=document.documentElement.scrollTop;};return{x:x||0,y:y||0};};Element_class.prototype.getViewport=function(){var windowSize=this.getWindowSize();var scrollOffset=this.getWindowScrollOffset();var top=scrollOffset.y;var bottom=scrollOffset.y+windowSize.height;var left=scrollOffset.x;var right=scrollOffset.x+windowSize.width;return{top:top,left:left,bottom:bottom,right:right,width:windowSize.width,height:windowSize.height};};
Element_class.prototype.importHTML = function(str) {var el = this.create("div"); el.innerHTML = str;var els = el.childNodes;return els;}
Element_class.prototype.is = function( domNode, selector, parent, propagate ) {
parent = parent || domNode.parentNode; var queriedEls = this.parseSelector(selector, parent);var  i, l = queriedEls.length;
while(domNode && domNode !== parent) {
for(i = 0; i < l; i++) { if(domNode === queriedEls[i]) { return true;}}
if(propagate) {domNode = domNode.parentNode;continue;} break;}return false;};


// Serializer.3.js
Serializer=function(){this._nameExclusions={};this._typeExclusions={};this._encode=true;this._strictJson=true;this._safeDeserialize=false;this._sBase64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";};Serializer.prototype.serialize=function(o){this._data=[];this._serializeNode([o],o,0);this._data=this._data.join("");this._data=this._data.replace(/,}/g,"}");this._data=this._data.replace(/,]/g,"]");this._data=this._data.substr(0,this._data.length-1);if(this.allowEncoding()){this._data=this.base64encode(this._data);}
return this._data;}
Serializer.prototype.addNameExclusion=function(){var l=arguments.length;for(var i=0;i<l;i++){this._nameExclusions[arguments[i]]=true;}}
Serializer.prototype.removeNameExclusion=function(){var l=arguments.length;for(var i=0;i<l;i++){this._nameExclusions[arguments[i]]=false;}}
Serializer.prototype.addTypeExclusion=function(){var l=arguments.length;for(var i=0;i<l;i++){this._typeExclusions[arguments[i].toLowerCase()]=true;}}
Serializer.prototype.removeTypeExclusion=function(){var l=arguments.length;for(var i=0;i<l;i++){this._typeExclusions[arguments[i].toLowerCase()]=false;}}
Serializer.prototype.requireStrictJson=function(value){if(typeof(value)!="undefined"){this._strictJson=value;}
return this._strictJson;}
Serializer.prototype.requireSafeDeserialize=function(value){if(typeof(value)!="undefined"){this._safeDeserialize=value;}
return this._safeDeserialize;}
Serializer.prototype.allowEncoding=function(value){if(typeof(value)!="undefined"){this._encode=value;}
return this._encode;}
Serializer.prototype._unicodeEscape=function(str){var dec=str.charCodeAt(0);var hexStr="\\u";var hexVals=['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];var hexPlace;hexPlace=4096
hexStr+=hexVals[Math.floor(dec/hexPlace)];dec=dec%hexPlace;hexPlace=256
hexStr+=hexVals[Math.floor(dec/hexPlace)];dec=dec%hexPlace;hexPlace=16
hexStr+=hexVals[Math.floor(dec/hexPlace)];dec=dec%hexPlace;hexPlace=1
hexStr+=hexVals[Math.floor(dec/hexPlace)];dec=dec%hexPlace;return hexStr;}
Serializer.prototype._serializeNode=function(o,startObj,depth,parentType){var t,f,d1,d2;for(var i in o){if(o[i]===null){t="null";}else{t=typeof(o[i]);}
f=t=="object"?true:false;t=t=="object"&&typeof(o[i].length)!="undefined"&&o[i].constructor==Array?"array":t;if(!this._typeExclusions[t]&&!this._nameExclusions[i]&&!(this._strictJson&&t=="function")){switch(t){case"string":d1="\"";d2="\"";break;case"object":d1="{";d2="}";break;case"array":d1="[";d2="]";break;default:d1="";d2="";break;}
if(isFinite(i)&&!(parentType&&parentType=="object")){this._data.push(d1);}else{var n=typeof(i)=="string"?"\""+i+"\"":i;this._data.push(n+":"+d1);}
if(f){if(depth==0||o[i]!==startObj){this._serializeNode(o[i],null,null,t);}}else{if(t=="string"){this._data.push(o[i].replace(/[^ -~]|[\"\\]/g,this._unicodeEscape));}else if(t=="undefined"||t=="null"){this._data.push(this._strictJson?"null":t);}else{this._data.push(o[i]);}}
this._data.push(d2+",");}}}
Serializer.prototype.deserialize=function(o){try{if(this.hasEncodingLeader(o)){o=this.base64decode(o);}
if(this._safeDeserialize){return this.safeDeserialize(o);}else{return this.unsafeDeserialize(o);}}catch(e){if(typeof(dbg)=="function"){dbg("Serializer.deserialize() error","","red");dbgObject(e);dbg("Serializer Source",o);}
var x="";}
return x;}
Serializer.prototype.safeDeserialize=function(o){try{var p=new jsonParser();p.parse(o);eval("var x = "+o);}catch(e){var x=null;}
return x;}
Serializer.prototype.unsafeDeserialize=function(o){try{eval("var x = "+o);}catch(e){var x=null;}
return x;}
Serializer.prototype.hasEncodingLeader=function(s){return s.indexOf("B64ENC")==0?true:false;}
Serializer.prototype.stripLeader=function(s){return s.substr(6,s.length);}
Serializer.prototype.prependLeader=function(s){return"B64ENC"+s;}
Serializer.prototype.base64decode=function(sIn){var i;var iBits;var sOut=[];if(this.hasEncodingLeader(sIn)){sIn=this.stripLeader(sIn);}else{return sIn;}
sIn=sIn.replace(/=/g,"");for(i=0;i<sIn.length;i+=4){iBits=(this._sBase64.indexOf(sIn.charAt(i))<<18)|(this._sBase64.indexOf(sIn.charAt(i+1))<<12)|((this._sBase64.indexOf(sIn.charAt(i+2))&0xff)<<6)|(this._sBase64.indexOf(sIn.charAt(i+3))&0xff);sOut.push(String.fromCharCode(iBits>>16&0xff));sOut.push((i>sIn.length-3)?"":String.fromCharCode(iBits>>8&0xff));sOut.push((i>sIn.length-4)?"":String.fromCharCode(iBits&0xff));}
return sOut.join("");}
Serializer.prototype.base64encode=function(sIn){var i;var iBits;var sOut=[];for(i=0;i<sIn.length;i+=3){iBits=(sIn.charCodeAt(i)<<16)+
((sIn.charCodeAt(i+1)&0xff)<<8)+
(sIn.charCodeAt(i+2)&0xff);sOut.push(this._sBase64.charAt(iBits>>18&0x3f));sOut.push(this._sBase64.charAt(iBits>>12&0x3f));sOut.push((i>sIn.length-2)?"=":this._sBase64.charAt(iBits>>6&0x3f));sOut.push((i>sIn.length-3)?"=":this._sBase64.charAt(iBits&0x3f));}
sOut=this.prependLeader(sOut.join(""));return sOut;}
function jsonParser(){this.lexer=null;this.tokens=[];}
jsonParser.prototype.parse=function(str){this.lexer=new jsonLexer(str);return this._json();}
jsonParser.prototype.lookAhead=function(k){while(this.tokens.length<=k){this.tokens.push(this.lexer.nextToken());}
return this.tokens[k].type;}
jsonParser.prototype.consume=function(type){if(this.tokens.length==0){this.tokens.push(this.lexer.nextToken());}
if(this.tokens[0].type==type){this.tokens.shift();}else{throw{message:'JSON: invalid token encountered validating string; Expected '+type+', got '+this.tokens[0].type};}}
jsonParser.prototype._json=function(){this._value();this.consume('_EOF');}
jsonParser.prototype._value=function(){switch(this.lookAhead(0)){case'_OBJ_OPEN':this._object();break;case'_ARR_OPEN':this._array();break;case'_DIGITS':case'_NEG':this._number();break;case'_STRING':this.consume('_STRING');break;case'_TRUE':this.consume('_TRUE');break;case'_FALSE':this.consume('_FALSE');break;case'_NULL':this.consume('_NULL');break;}}
jsonParser.prototype._object=function(){this.consume('_OBJ_OPEN');if(this.lookAhead(0)!='_OBJ_CLOSE'){this._member();}
while(this.lookAhead(0)!='_OBJ_CLOSE'){this.consume('_SEP');this._member();}
this.consume('_OBJ_CLOSE');}
jsonParser.prototype._member=function(){this.consume('_STRING');this.consume('_ASSIGN');this._value();}
jsonParser.prototype._array=function(){this.consume('_ARR_OPEN');if(this.lookAhead(0)!='_ARR_CLOSE'){this._value();}
while(this.lookAhead(0)!='_ARR_CLOSE'){this.consume('_SEP');this._value();}
this.consume('_ARR_CLOSE');}
jsonParser.prototype._number=function(){if(this.lookAhead(0)=='_NEG'){this.consume('_NEG');}
this.consume('_DIGITS');if(this.lookAhead(0)=='_DOT'){this.consume('_DOT');this.consume('_DIGITS');}
if(this.lookAhead(0)=='_EXP'){this.consume('_EXP');if(this.lookAhead(0)=='_POS'){this.consume('_POS');}else if(this.lookAhead(0)=='_NEG'){this.consume('_NEG');}
this.consume('_DIGITS');}}
function jsonLexer(input){input=input.replace(/"([^"\\]|\\"|\\)*"/g,'S');input=input.replace(/[0-9]+/g,'0');this.input=input;}
jsonLexer.prototype.charTokens={'{':'_OBJ_OPEN','}':'_OBJ_CLOSE','[':'_ARR_OPEN',']':'_ARR_CLOSE',':':'_ASSIGN',',':'_SEP','.':'_DOT','-':'_NEG','+':'_POS','e':'_EXP','E':'_EXP','S':'_STRING','0':'_DIGITS'};jsonLexer.prototype.nextToken=function(){if(this.input.length==0){return new jsonToken("_EOF",null);}
var first=this.input.substr(0,1);if(this.charTokens[first]){this.input=this.input.substr(1);return new jsonToken(this.charTokens[first],first);}
switch(first){case't':case'T':if(this.input.substr(0,4).toLowerCase()=='true'){this.input=this.input.substr(4);return new jsonToken('_TRUE',true);}
break;case'f':case'F':if(this.input.substr(0,5).toLowerCase()=='false'){this.input=this.input.substr(5);return new jsonToken('_FALSE',true);}
break;case'n':if(this.input.substr(0,4)=='null'){this.input=this.input.substr(4);return new jsonToken('_NULL',true);}
break;}
throw{message:'JSON: Unexpected character ('+first+') encountered validating string'};}
function jsonToken(type,value){this.type=type;this.value=value;}

// ContentBuffer.4.js
if(typeof Controller=="undefined")
{if(typeof dbg!="function")
{var dbg=function(){};};}
else
{Controller.require("/includes/jslib/debug.js");};function ContentBuffer()
{this.connections=[];this.connectionsMax=100;this.connectionsActive=0;this.connectionsPending=[];this.debug=false;this.context=window;this.connectionId=0;if(arguments.length&&typeof arguments[0]=="object")
{this.context=arguments[0];};};ContentBuffer.prototype.load=function(contentPackage)
{if(typeof Controller=="undefined")
{};try
{contentPackage.method=contentPackage.method.toLowerCase();if(contentPackage.method!="get"&&contentPackage.method!="post")
{contentPackage.method="get";};}
catch(e)
{contentPackage.method="get";};if(contentPackage.postdata&&!contentPackage.data)
{contentPackage.data=contentPackage.postdata;}
else if(!contentPackage.data)
{contentPackage.data={};};if(document.location.search.match(/\.\.nocache\.\.=on/i))
{contentPackage.data["..nocache.."]="on";};var dbgChartSrv=document.location.search.match(/\.\.debugchartsrv\.\.=([a-zA-Z]+)/i);if(dbgChartSrv){contentPackage.data["..debugchartsrv.."]=dbgChartSrv[1];}
return new Connection(this,this.connectionId++,contentPackage);};ContentBuffer.prototype._loadXMLHTTP=function(connection){var thisConnection=connection;var contentPackage=thisConnection.contentPackage;function stateMonitor(){thisBuffer._monitorConnectionState(thisConnection);};this.connectionsActive++;var dataPackage=null;var thisBuffer=this;thisConnection.active=true;if(typeof contentPackage.contentType=="string"){contentPackage.data["..contenttype.."]=contentPackage.contentType;};contentPackage.data["..requester.."]="ContentBuffer";if(contentPackage.method=="post"){dataPackage="";for(var i in contentPackage.data){dataPackage+=(dataPackage.length?"&":"")+this.encode(i)+"="+this.encode(contentPackage.data[i]);};if(this.debug||contentPackage.debug){dbg("ContentBuffer post data",dataPackage);};}else{for(var i in contentPackage.data){contentPackage.url+=(contentPackage.url.indexOf("?")==-1?"?":"&")+this.encode(i)+"="+this.encode(contentPackage.data[i]);};};if(this.debug||contentPackage.debug){dbg("ContentBuffer loading ["+thisConnection.connectionId+"]",contentPackage.url+" ["+contentPackage.method+"]");};if(this.debug||contentPackage.debug){var debugUrl=contentPackage.url;if(dataPackage){debugUrl+=(debugUrl.indexOf("?")==-1?"?":"&")+dataPackage;};debugUrl=debugUrl.replace(/\&?\.\.[^\=\&]*\.\.\=[^\&]*/g,"");if(debugUrl.indexOf("/")!=0&&debugUrl.indexOf("http")!=0){var path=String(window.location).replace(/https*:\/\//,"");debugUrl=path.substr(path.indexOf("/"),path.lastIndexOf("/")+1-path.indexOf("/"))+debugUrl;}
dbg("ContentBuffer URL","<a href=\""+debugUrl+"\"  target=\"_blank\">"+debugUrl+"</a>");};try{thisConnection.c.open(contentPackage.method.toUpperCase(),contentPackage.url,true);thisConnection.c.onreadystatechange=stateMonitor;}catch(e){};if(contentPackage.method=="post"){thisConnection.c.setRequestHeader("Content-Type","application/x-www-form-urlencoded");};thisConnection.c.send(dataPackage);};ContentBuffer.prototype._monitorConnectionState=function(connection){if(connection.c.readyState==4){if(connection.c.status!=200){if(this.debug||connection.contentPackage.debug){dbg("ContentBuffer load error",connection.c.status,"red");dbg("ContentBuffer result ["+connection.connectionId+"]",connection.c.responseText);};try{var result=connection.c.responseText;}catch(e){var result=null;};connection.contentPackage.result=result;if(typeof connection.contentPackage.onerror=="function"){connection.contentPackage.onerror.apply(connection.context,[connection]);};return;};var responseType=connection.contentPackage.contentType||connection.c.getResponseHeader("Content-Type");var result=null;if(responseType=="text/html"||responseType=="text/plain"){result=connection.c.responseText;}else if(responseType=="text/xml"){result=connection.c.responseXML;}else if(responseType=="text/javascript"){result=connection.c.responseText;if(!connection.contentPackage.preventEval){connection.context.__evalBuffer=function(){eval(result);}
connection.context.__evalBuffer();};};connection.contentPackage.result=result;if(this.debug||connection.contentPackage.debug){};if(typeof connection.contentPackage.onload=="function"){connection.contentPackage.onload.apply(connection.context,[connection]);};connection.active=false;this.connectionsActive--;if(this.connectionsPending.length){this._loadXMLHTTP(this.connectionsPending.shift());};};};ContentBuffer.prototype.isActive=function(){for(var i=0;i<this.connections.length;i++){if(this.connections[i].active){return true;}}
return false;}
ContentBuffer.prototype.abortRequests=function(){for(var i=0;i<this.connections.length;i++){this.connections[i].abort();};}
ContentBuffer.prototype.abortRequests=function(){for(var i=0;i<this.connections.length;i++){this.connections[i].abort();};}
ContentBuffer.prototype.encode=function(str){return encodeURIComponent(str);}
function Connection(contentBuffer,id,contentPackage){this.active=false;this.parent=contentBuffer;this.connectionId=id;this.contentPackage=contentPackage;this.context=contentPackage.context||this.parent.context;this._init();};Connection.prototype._init=function(){var c=false;try{c=new ActiveXObject("Msxml2.XMLHTTP");}catch(e){try{c=new ActiveXObject("Microsoft.XMLHTTP");}catch(f){c=false;};};if(!c&&typeof XMLHttpRequest!="undefined"){c=new XMLHttpRequest();};if(c){this.c=c;}else{dbg("Content Buffer initialization error.","Not supported by this browser","red");};if(this.parent.connectionsActive<this.parent.connectionsMax){this.parent.connections.push(this);this.parent._loadXMLHTTP(this);}else{dbg("queuing request");this.parent.connectionsPending.push(this);};};Connection.prototype.getResult=function(){return this.contentPackage.result;};Connection.prototype.status=function(){return(this.c.readyState==4&&this.c.status==200);};Connection.prototype.abort=function(){if(this.active){try{this.c.onreadystatechange=function(){};this.c.abort();}catch(e){dbg("connection abort failed",e,"red");};};};

// Events.3.js
var EventSource=function(type){this.listeners=[];this.type=type;};EventSource.prototype.addListener=function(listener,context){if(listener instanceof Function){listener={handler:listener,context:context}}
if(!listener.context){listener.context=window;}
this.listeners.push(listener);return listener;};EventSource.prototype.removeListener=function(listener){for(var i=0;i<this.listeners.length;i++){if(listener==this.listeners[i]){this.listeners.splice(i);}}};EventSource.prototype.removeAll=function(){this.listeners=[];};EventSource.prototype.fire=function(){Array.prototype.unshift.call(arguments,this.type);for(var i=0;i<this.listeners.length;i++){this.listeners[i].handler.apply(this.listeners[i].context,arguments);}};var DOMEventSource=function(type){DOMEventSource.Super(this,null,arguments);this.delayTimeouts=[];this.typeIE="on"+this.type;this.elements=[];};DOMEventSource.Extend(EventSource);DOMEventSource.prototype._getBrowserEventName=function(){switch(this.type){case"load":case"change":case"reset":case"select":case"submit":case"blur":case"focus":case"resize":case"scroll":case"abort":case"error":case"unload":return"HTMLEvents";case"mouseover":case"mouseout":case"click":case"dblclick":case"mouseup":case"mousedown":case"mouseenter":case"mouseleave":case"mousemove":case"contextmenu":case"dragstart":case"selectstart":return"MouseEvents";case"keypress":case"keydown":case"keyup":return"UIEvents";default:return null;}};DOMEventSource.prototype._validateEvent=function(e,listener){if(listener.keyCode&&"UIEvents"==this._getBrowserEventName()){return listener.keyCode==e.nativeEvent.keyCode;}
return true;};DOMEventSource.prototype._createDOMHandlerClosure=function(listener,element){var theDOMEventSource=this;for(var i=0,DOMHandler;i<element.length;i++){DOMHandler=function(){var el=element[i].node;if(listener.delay){return function(){var e=window.event||arguments[0];var newEvt={};for(var i in e){newEvt[i]=e[i];}
e=new DOMEvent(newEvt);theDOMEventSource.clearDelayTimeouts();theDOMEventSource.delayTimeouts.push(window.setTimeout(function(){if(theDOMEventSource._validateEvent(e,listener)){listener.handler.call(listener.context,e,el,listener.data);}},listener.delay));}}
else{return function(){var e=new DOMEvent(window.event||arguments[0]);if(theDOMEventSource._validateEvent(e,listener)){listener.handler.call(listener.context,e,el,listener.data);}}}}();this._addEventListener(element[i].node,DOMHandler);element[i].registeredListeners.push({DOMHandler:DOMHandler,listener:listener});}};DOMEventSource.prototype.addElement=function(element,removeIfExisting){if(!(element instanceof Array)){element=[element];}
if(removeIfExisting){this.removeElement(element);}
var elements=[];for(var i=0;i<element.length;i++){elements.push({node:element[i],registeredListeners:[]});}
for(var i=0;i<this.listeners.length;i++){this._createDOMHandlerClosure(this.listeners[i],elements);}
this.elements=this.elements.concat(elements);};DOMEventSource.prototype.removeElement=function(element){var element=[].concat(element);for(var i=0,elWrapper;i<this.elements.length;i++){elWrapper=this.elements[i];if(!element.length){break;}
for(var j=0,el;j<element.length;j++){el=element[j];if(elWrapper.node===el){for(var k=0;k<elWrapper.registeredListeners.length;k++){this._removeEventListener(el,elWrapper.registeredListeners[k].DOMHandler);}
element.splice(j,1);this.elements.splice(i,1);j--;i--;}}}};DOMEventSource.prototype.removeAll=function(){this.removeAllElements();this.listeners=[];};DOMEventSource.prototype.removeAllElements=function(){for(var i=0,el;i<this.elements.length;i++){el=this.elements[i];for(var j=0;j<el.registeredListeners.length;j++){this._removeEventListener(el.node,el.registeredListeners[j].DOMHandler);}}
this.elements=[];};DOMEventSource.prototype.addListener=function(listener,context,delay){if(listener instanceof Function){listener={handler:listener,context:context,delay:delay}}
if(!listener.context){listener.context=window;}
this._createDOMHandlerClosure(listener,this.elements);this.listeners.push(listener);return listener;};DOMEventSource.prototype.removeListener=function(listener){for(var i=0,el;i<this.elements.length;i++){el=this.elements[i];for(var j=0,rl;j<el.registeredListeners.length;j++){rl=el.registeredListeners[j];if(rl.listener==listener){this._removeEventListener(el.node,rl.DOMHandler);el.registeredListeners.splice(j,1);break;}}}
for(var i=0,listener;i<this.listeners.length;i++){if(listener==this.listeners[i]){this.listeners.splice(i,1);break;}}};DOMEventSource.prototype.fire=function(element){if(undefined==element){for(var i=0;i<this.elements.length;i++){this._dispatchEvent(this.elements[i].node);}}
else{if(!(element instanceof Array)){element=[element];}
for(var i=0;i<element.length;i++){this._dispatchEvent(element[i]);}}};DOMEventSource.prototype._addEventListener=function(el,handler){if(document.attachEvent){DOMEventSource.prototype._addEventListener=function(el,handler){el.attachEvent(this.typeIE,handler);};}
else if(document.addEventListener){DOMEventSource.prototype._addEventListener=function(el,handler){el.addEventListener(this.type,handler,false);};}
this._addEventListener=DOMEventSource.prototype._addEventListener;this._addEventListener(el,handler);};DOMEventSource.prototype._removeEventListener=function(el,handler){if(el.detachEvent){DOMEventSource.prototype._removeEventListener=function(el,handler){el.detachEvent(this.typeIE,handler);};}
else if(el.removeEventListener){DOMEventSource.prototype._removeEventListener=function(el,handler){el.removeEventListener(this.type,handler,false);};}
this._removeEventListener=DOMEventSource.prototype._removeEventListener;this._removeEventListener(el,handler);};DOMEventSource.prototype._dispatchEvent=function(el){if(document.createEventObject){DOMEventSource.prototype._dispatchEvent=function(el){var event=document.createEventObject();event.srcElement=el;event.type=this.type;el.fireEvent(this.typeIE,event);};}
else{DOMEventSource.prototype._dispatchEvent=function(el){var event=document.createEvent(this._getBrowserEventName(this.type));event.initEvent(this.type,true,true);el.dispatchEvent(event);};}
this._dispatchEvent=DOMEventSource.prototype._dispatchEvent;this._dispatchEvent(el);};DOMEventSource.prototype.clearDelayTimeouts=function(){for(var i=0;i<this.delayTimeouts.length;i++){window.clearTimeout(this.delayTimeouts[i]);}
this.delayTimeouts=[];};var DOMEvent=function(nativeEvent){this.nativeEvent=nativeEvent;};DOMEvent.prototype.cancel=function(){if(this.nativeEvent.stopPropagation){this.nativeEvent.stopPropagation();}
else{try{this.nativeEvent.cancelBubble=true;}catch(e){}}
if(this.nativeEvent.preventDefault){this.nativeEvent.preventDefault();}
else{try{this.nativeEvent.returnValue=false;}catch(e){}}
return this.nativeEvent;};DOMEvent.prototype.getTarget=function(){var target=this.nativeEvent.srcElement||this.nativeEvent.target;this.getTarget=function(){return target;}
return this.getTarget();};var EventManager=function(){this.events=[];this.add(window,"unload",this.removeAll,this);};EventManager.prototype.KEYCODES={Backspace:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,CAPS:20,ESCAPE:27,PAGEUP:33,PAGEDOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,INSERT:45,DELETE:46,SPACE:32,COMMAND:224}
EventManager.prototype.add=function(element,type,handler,context,data,delay,keyCode){if(arguments.length>1){var inputs={element:element,type:type,handler:handler,context:context,data:data,delay:delay,keyCode:keyCode}}
else if(arguments[0]instanceof Object){var inputs=arguments[0];}
else{var inputs={type:arguments[0]}}
var listener={handler:inputs.handler,context:inputs.context,delay:inputs.delay,data:inputs.data,keyCode:inputs.keyCode};if(this._isDomEventType(inputs.type)){var e=this._addDOMEvent(inputs.type,listener,inputs.element);}
else{var e=this._addCustomEvent(inputs.type,listener);}
this.events.push(e);return e;};EventManager.prototype._isDomEventType=function(type){if(null==DOMEventSource.prototype._getBrowserEventName.apply({type:type})){return false;}
return true;};EventManager.prototype._addDOMEvent=function(type,listener,element){var e=new DOMEventSource(type);if(listener.handler){e.addListener(listener);}
if(element){e.addElement(element);}
return e;};EventManager.prototype._addCustomEvent=function(type,listener){var e=new EventSource(type);if(listener.handler){e.addListener(listener);}
return e;};EventManager.prototype.remove=function(e,listener){if(e instanceof EventSource){this._removeEvent(e,listener);}
else if(e.nodeName||e instanceof Array){this._removeElement(e,listener);}};EventManager.prototype._removeEvent=function(e,listener){if(undefined==listener){e.removeAll();}else{e.removeListener(listener);}
for(var i=0;i<this.events.length;i++){if(e==this.events[i]){this.events.splice(i,1);break;}}};EventManager.prototype._removeElement=function(el,eventType){for(var i=0,event;i<this.events.length;i++){event=this.events[i];if(event instanceof DOMEventSource){if(!eventType||(event.type==eventType)){event.removeElement(el);}}}};EventManager.prototype.removeAll=function(){for(var i=0;i<this.events.length;i++){this.events[i].removeAll();}
this.events=[];};EventManager.prototype.cancel=function(e){if(!e){return;}
if(e instanceof DOMEvent){e.cancel();}
else if(e.srcElement||e.target){DOMEvent.prototype.cancel.apply({nativeEvent:e});}};if(window["WSDOM"]){WSDOM.defineClass("Events",null,EventManager);WSDOM.loadSingleton("WSDOM.Events.3");}else{var Events=new EventManager();}
Events.cancelEvent=Events.cancel;function getNativeEvent(e){return e.nativeEvent||e;}

//Events.Delegate

EventManager.prototype.Delegation = {

	 SuperClass:null
	 
	,isDelegator:function( el, delegators ) {

		var len = delegators.length;

		while(len--) {
			if(el === delegators[len]) {
				return true;	
			}
		}
		return false;
	}
	
	,prepArgs:function( o ) {

		o.context = o.context || window;
		o.handler = String === o.handler.constructor? o.context[ o.handler ] : o.handler;

		if( o.dynamicEvent ) {

			var self = this;

			o.dynamicEvent    = this.prepArgs( o.dynamicEvent );
			o.dynamicEvent.fn = function( e, el, data ) {

				var d = o.dynamicEvent;
					d.handler.call( d.context, e, el, data );
				
				var evs = self.SuperClass.events;
				var len = evs.length;
				
				while(len--) {	/* Loop backwards b/c its more likely the event is at the end of the stack */
					
					if(evs[len].elements[0].node === el) {	/* there will always only be one element */

						evs[len].removeAll();
						evs.splice( len, 1 );
						break;
					}
				}
			}
		}
		return o;
	}
	
	,assign:function( SuperClass, delegator, type, oArgs ) {
		
		this.SuperClass = this.SuperClass || SuperClass;
		
		delegator = Element.get(delegator) || Element.parseSelector(delegator);
		oArgs	  = Array.prototype.concat( oArgs );
		
		var len = oArgs.length;
		
		while(len--) {
			oArgs[len] = this.prepArgs( oArgs[len] );	
		}

		var self = this;
		var fn   = function(e, el, data){
			
			var target = e.getTarget();
		
			if( self.isDelegator(target, delegator) ) {
				return;
			}

			var  l = oArgs.length
				,cur;

			while(l--) {

				cur = oArgs[l];

				if(Element.is(target, cur.selector, el, true)) {

					if( cur.dynamicEvent ) {

						var de = cur.dynamicEvent;
			       		var ev = self.SuperClass.add( target, de.type, de.fn, de.context, de.data );
			       	}
			       	
					e.delegator = el;
					cur.handler.call(cur.context, e, target, cur.data);
				}
			}
		};
		
		return this.SuperClass.add( delegator, type, fn );
	}	
}

EventManager.prototype.delegate = function( delegator, type, oArgs ) {
	
	return this.Delegation.assign( this, delegator, type, oArgs );
}

// Fader.1.js
function Fader(){};Fader.prototype.INTERVAL=3;Fader.prototype.FRAME_TIME=5;Fader.prototype.MAX_ANIMATION_TIME=1000;Fader.prototype.START_OPACITY=0;Fader.prototype.FINISH_OPACITY=100;Fader.prototype.fadeIn=function(el){return this.initFadeTimeouts(el,function(value,stop){return Math.ceil(this.getTweenIn(value,stop))},this.START_OPACITY,this.FINISH_OPACITY);};Fader.prototype.fadeOut=function(el,removeFromDOM){return this.initFadeTimeouts(el,function(value,stop){return Math.floor(this.getTweenOut(value,stop))},this.FINISH_OPACITY,this.START_OPACITY,removeFromDOM);};Fader.prototype.initFadeTimeouts=function(el,fnTween,startOpacity,finishOpacity,removeFromDOM){this.clearFadeTimeouts(el);var finishTime=new Date().getTime()+this.MAX_ANIMATION_TIME;var theFader=this;var fadeComplete=new EventSource("fadeComplete");var getFadeFunctionClosure=function(opacity){return function(){theFader.fade(opacity,el,finishOpacity,finishTime,removeFromDOM,fadeComplete);};};el._faderOpacity=el._faderOpacity||startOpacity;var startFade=Math.floor(Math.min(el._faderOpacity,finishOpacity));var stopFade=Math.ceil(Math.max(el._faderOpacity,finishOpacity));for(var i=startFade,delay,opacity;i<=stopFade;i+=this.INTERVAL){delay=(i-startFade)*this.FRAME_TIME;opacity=fnTween.call(this,i,stopFade);el._faderTimeouts.push(setTimeout(getFadeFunctionClosure(opacity),delay));}
return fadeComplete;};Fader.prototype.fade=function(opacity,el,finishOpacity,finishTime,removeFromDOM,fadeComplete){var now=new Date().getTime();if(now>finishTime){opacity=finishOpacity;}
Element.setOpacity(el,opacity);el._faderOpacity=opacity;if(opacity==finishOpacity){this.clearFadeTimeouts(el);if(removeFromDOM){this.clearFadeProperties(el);Element.remove(el);}
fadeComplete.fire(el);}};Fader.prototype.clearFadeProperties=function(el){try{delete el._faderOpacity;delete el._faderTimeouts;}
catch(e){}};Fader.prototype.getTweenIn=function(value,stop){return(1-Math.cos((value/stop)*Math.PI))/2*stop;};Fader.prototype.getTweenOut=function(value,stop){return stop-this.getTweenIn(value,stop);};Fader.prototype.clearFadeTimeouts=function(el){if(el._faderTimeouts){for(var i=0;i<el._faderTimeouts.length;i++){clearTimeout(el._faderTimeouts[i]);}}
el._faderTimeouts=[];};

// wch.js Slightly modified to fix bugs 
var WCH_Constructor=function(){if(!(document.all&&document.getElementById&&!window.opera&&navigator.userAgent.toLowerCase().indexOf("mac")==-1))
{this.Apply=function(){};this.Discard=function(){};return;}var _bIE55=false;var _bIE6=false;var _oRule=null;var _bSetup=true;var _oSelf=this;this.Apply=function(vLayer,vContainer,bResize)
{if(_bSetup)_Setup();if(_bIE55&&(oIframe=_Hider(vLayer,vContainer,bResize))){oIframe.style.visibility="visible";}
else if(_oRule!=null){_oRule.style.visibility="hidden";}};this.Discard=function(vLayer,vContainer){if(_bIE55&&(oIframe=_Hider(vLayer,vContainer,false))){oIframe.style.visibility="hidden";}
else if(_oRule!=null){_oRule.style.visibility="visible";}};function _Hider(vLayer,vContainer,bResize)
{var oLayer=_GetObj(vLayer);var oContainer=((oTmp=_GetObj(vContainer))?oTmp:document.getElementsByTagName("body")[0]);if(!oLayer||!oContainer)return;var oIframe=document.getElementById("WCHhider"+oLayer.id);if(!oIframe)
{var sFilter=(_bIE6)?"filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0);":"";var zIndex=oLayer.style.zIndex;if(zIndex=="")zIndex=oLayer.currentStyle.zIndex;zIndex=parseInt(zIndex);if(isNaN(zIndex))return null;if(zIndex<2)return null;zIndex--;var sHiderID="WCHhider"+oLayer.id;oContainer.insertAdjacentHTML("afterBegin",'<iframe class="WCHiframe" src="javascript:false;" id="'+sHiderID+'" scroll="no" frameborder="0" style="position:absolute;visibility:hidden;'+sFilter+'border:0;top:0;left;0;width:0;height:0;background-color:#ccc;z-index:'+zIndex+';"></iframe>');oIframe=document.getElementById(sHiderID);_SetPos(oIframe,oLayer);}
else if(bResize){_SetPos(oIframe,oLayer);}var zIndex=oLayer.style.zIndex;if(zIndex=="")zIndex=oLayer.currentStyle.zIndex;zIndex=parseInt(zIndex);if(isNaN(zIndex))return null;if(zIndex<2)return null;zIndex--;oIframe.style.zIndex=zIndex;return oIframe;};function _SetPos(oIframe,oLayer)
{oIframe.style.width=oLayer.offsetWidth+"px";oIframe.style.height=oLayer.offsetHeight+"px";oIframe.style.left=oLayer.offsetLeft+"px";oIframe.style.top=oLayer.offsetTop+"px";};function _GetObj(vObj){var oObj=null;switch(typeof(vObj))
{case"object":oObj=vObj;break;case"string":oObj=document.getElementById(vObj);break;}return oObj;};function _Setup()
{_bIE55=(typeof(document.body.contentEditable)!="undefined");_bIE6=(typeof(document.compatMode)!="undefined");if(!_bIE55)
{if(document.styleSheets.length==0)document.createStyleSheet();var oSheet=document.styleSheets[0];oSheet.addRule(".WCHhider","visibility:visible");_oRule=oSheet.rules(oSheet.rules.length-1);}
_bSetup=false;};};var WCH=new WCH_Constructor();

if (!window.console || !console.firebug) {
	var console = {
		log: function() {},
		group: function() {},
		groupEnd: function() {}
	}
}

WSDOM = new function() {
	var loadedClasses = {};
	var usingReferences = [];

	this.defineClass = function(className, superClass, constructor) {
		loadedClasses[className] = constructor;

		if (null != superClass) {
			loadedClasses[className].Extend(superClass);
		}

		// both classes and instances should have references to their names
		loadedClasses[className].prototype.getClassName = function() {
			return className;
		};
		loadedClasses[className].getClassName = loadedClasses[className].prototype.getClassName;

		return loadedClasses[className];
	};

	this.loadClass = function(className) {
		var classDef = parseClassName(className);

		var o = this.getClass(classDef.className);
		if (o) {
			this[o.getClassName()] = o;
			this[o.getClassName()].prototype.namespace = classDef.namespace;
			this[o.getClassName()].prototype.version = classDef.version;
		};
	};

	this.loadSingleton = function(className) {
		var classDef = parseClassName(className);

		var o = this.getClass(classDef.className);
		if (o) {
			this[o.getClassName()] = new o();
			this[o.getClassName()].namespace = classDef.namespace;
			this[o.getClassName()].version = classDef.version;
		};
	};

	this.getClass = function(className) {
		return loadedClasses[className];
	};

	this.getLoadedClasses = function() {
		return loadedClasses;
	};

	this.using = function(originatingClassName, className) {
		usingReferences.push({originatingClassName:originatingClassName, className:className});
	}


	this._processUsingReferences = function() {

		var usingErrors = false;
		for (var x = 0; x < usingReferences.length; x++) {

			var originatingClassName = usingReferences[x].originatingClassName;
			var className = usingReferences[x].className;
			var classDef = parseClassName(className);

			if (!this[classDef.className]) {
				if (this.Console) {
					this.Console.warn("Missing class definition for " + className + ".  Called from " + originatingClassName + ".");
				};
				usingErrors = true;
			} else if (this[classDef.className].version != classDef.version && (!this[classDef.className].prototype || this[classDef.className].prototype.version != classDef.version)) {
				if (this.Console) {
					this.Console.warn("Version incompatibility for loaded class, " + classDef.className + "." + this[classDef.className].version + ", versus requested class, version " + classDef.version + ".  Called from " + originatingClassName + ".");
				};
				usingErrors = false;
			};

		};
		if (!usingErrors && this.Console) {
			this.Console.log("WSDOM Framework loaded successfully.");
		};
	};




	/* Light-weight 'onload' for management of 'using' statements */
	this._onload = function() {
		var element = window;
		var eventType = "load";
		var fnHandler = this._processUsingReferences.Context(this);

		if (element.addEventListener) {
			// firefox
			element.addEventListener(eventType, fnHandler, false);
		}
		else if (element.attachEvent) {
			// ie
			element.attachEvent("on" + eventType, fnHandler);
		};
	};
	this._onload();


	function parseClassName(className) {
		var tokens = className.split('.');

		var classDef = {
			namespace:tokens[0],
			className:tokens[1],
			version:tokens[2]
		};

		return classDef;
	};



	this.identity = function(x) { return x };

}();

function capitalizeString ( st ) {
		
	st = st.split(/\s+/);
	
	var i	  	= 0,
		len   	= st.length,
		chunk 	= new Array(),
		noAlter = /^(the|or|and|to)$/;
		
	for(; i < len; i++) {
		
		if(noAlter.test(st[i]) && i) {
			
			chunk.push(st[i], ' ');
			continue;
		}
		
		chunk.push(
			 st[i].slice(0,1).toUpperCase()
			,st[i].slice(1)
			,' '
		);
	}
	
	return chunk.join('');
};

WSDOM.using("WSDOM.Element.3", "WSDOM.Events.2");
WSDOM.defineClass("Element", null, Element_class);
WSDOM.loadSingleton("WSDOM.Element.3");

WSDOM.using("WSDOM.Serializer.3", "WSDOM.Console.1");
WSDOM.defineClass("Serializer", null, Serializer);
WSDOM.loadSingleton("WSDOM.Serializer.3");

WSDOM.defineClass("Events", null, EventManager);
WSDOM.loadSingleton("WSDOM.Events.3");
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/Common.js
*/

var Common_Class = function() {
}


Common_Class.prototype.getContentBuffer = function() {
	var contentBuffer = new ContentBuffer();

	this.getContentBuffer = function() {
		return contentBuffer;
	}

	return this.getContentBuffer();
}


Common_Class.prototype.getSerializer = function() {
	var serializer = new Serializer();

	this.getSerializer = function() {
		return serializer;
	}

	return this.getSerializer();
}


Common_Class.prototype.validateEmail = function (email) {
	email = email || [];

	var emailArray = (email instanceof Array) ? email : [ email ];

	var pattern = /([\d\w_-]+)+@([\d\w_-]+)+\.([\d\w_-]+)+/i;

	for (var i = 0; i < emailArray.length; i++) {
		if (!pattern.test(emailArray[i])) {
			return false;
		}
	}

	return true;
}

Common_Class.prototype.focusText = function(e, el) {
	if (el.value == el.getAttribute("defaultText")) {
		WSDOM.Element.removeClass(el, "defaultText");
		el.value = "";
	}
}

Common_Class.prototype.blurText = function(e, el) {
	if (!el.value) {
		WSDOM.Element.addClass(el, "defaultText");
		el.value = el.getAttribute("defaultText");
	}
}

Common_Class.prototype.convertArrayToObject = function(arr, key) {
	var obj = {};
	for (var i = 0; i < arr.length; i++) {
		if (key) {
			obj[arr[i][key]] = arr[i];
		} else {
			obj[arr[i]] = true;
		}
	}

	return obj;
}

Common_Class.prototype.convertObjectToArray = function(obj) {
	var arr = [];
	for (var i in obj) {
		arr.push(obj[i]);
	}
	
	return arr;
}


Common_Class.prototype.mergeObjects = function() {
	if (!arguments.length) {
		return;
	}

	if (1 == arguments.length) {
		return arguments[0];
	}

	var obj = arguments[0];

	for (var i = 1, mergeObj; i < arguments.length; i++) {
		mergeObj = arguments[i];

 		for (var j in obj) {
			if (mergeObj[j]) {
				for (var k in mergeObj[j]) {
					obj[j][k] = mergeObj[j][k];
				}
			}
		}
	}

	return obj;
}


var Common = new Common_Class();

/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/utils.js
*/
function trim(string) { 
	return string.replace(/^\s+/, '').replace(/\s+$/, ''); 
};

function trimString(args) {
	args = args || {};
	var value = args.value;
	var chars = args.chars || 25;
	var tail = args.tail || "...";
	var searchwidth = args.searchwidth;
	
	if (value.length > chars){
		var w = (searchwidth)?searchwidth:30
		for (var chr=0; chr < w; chr++){
			if ((value.length >= (chars+chr)) && (/\s/i.test(value.charAt(chars + chr)))){
				return value.substring(0, chars + chr) + tail
			} else if ((chars - chr > 0) && (/\s/i.test(value.charAt(chars-chr)))){
				return value.substring(0, chars - chr) + tail
			}
		}
		return value.substring(0, chars) + tail

	} else {
		return value;
	}	
};

function popNewsStory(e, el, data) {
	e.cancel();
	
	var view = Element.getWindowSize();
	var url = el.getAttribute("href");
	window.open(url, "ftNews", "menubar=1,resizable=1,scrollbars=1,toolbar=1,location=1,directories=1,top="+0+",left="+0+",width="+view.width+",height="+view.height);
};

function CopyObj(obj) {
	var Copy;
	
	if (obj != null){
		Copy = new obj.constructor;

		for (var property in obj) {
			if (typeof(obj[property]) == "object" && obj[property] !== null) {
				Copy[property] = CopyObj(obj[property]);

			} else {
				Copy[property] = obj[property];
			}
		}
	}

	return Copy;
};

function jsToMsDate(jsdate) {
	var timezoneOffset = jsdate.getTimezoneOffset() / (60 * 24);
	var msDateObj = (jsdate.getTime() / 86400000) + (25569 - timezoneOffset);
	return msDateObj;
};

function msToJsDate(msdate) {
	var jscriptDateObj = new Date(((msdate - 25569) * 86400000));
	var timezoneOffset = jscriptDateObj.getTimezoneOffset();
	var jscriptDateObj = new Date(((msdate - 25569 + (timezoneOffset / (60 * 24))) * 86400000));
	return jscriptDateObj;
};

/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/Popup.js
*/
function Popup() {
	
	// defaults
	this.hasCloseLink(true);
	this.hasTitle(true);

    this.log(arguments.callee.caller);
};

Popup.prototype.CSS_MAIN = "popup";
Popup.prototype.CSS_INNER = "popupInner";
Popup.prototype.CSS_HEADER = "popupHeader";
Popup.prototype.CSS_CONTENT = "popupContent";

Popup.prototype.CSS_HIDDEN = "wsodHidden";

Popup.prototype.log = function (caller)
{
    if(caller == Function.Extend){ return; }
    if(!Popup.instances){ Popup.instances = new Array(); }
    Popup.instances.push(this);
}

Popup.prototype.hasCloseLink = function(value) {
	if (undefined !== value) {
		this._hasCloseLink = value;
	}
	return this._hasCloseLink;
};

Popup.prototype.hasTitle = function(value) {
	if (undefined !== value) {
		this._hasTitle = value;
	}
	return this._hasTitle;
};

Popup.prototype.getEventManager = function() {
	var em = new EventManager();
	this.getEventManager = function() {
		return em;
	};
	return this.getEventManager();
};

Popup.prototype.getParent = function() {
	//var parent = Element.get("wsod");
	var parent = Element.get("wsodPop");
	if(!parent){
		parent = Element.create("div", {id:"wsodPop"}, null, document.body);
	}
	this.getParent = function() { return parent; };
	
	return this.getParent();
};

Popup.prototype.setParent = function(parent) {
	this.getParent = function() { return parent; };
};

Popup.prototype.getFrame = function() {
	var closeLink = title = document.createDocumentFragment();
	
	if (this.hasCloseLink()) {
		closeLink = this.getCloseLink();
	}
	
	if (this.hasTitle()) {
		title = this.getTitle();	
	}
	
	var frame = Element.create('div', { "class": this.CSS_MAIN }, [
		Element.create("iframe", { "src": "javascript:false;", "frameborder": 0 }),
		Element.create('div', { "class": this.CSS_INNER }, [
			// dumb header container
			Element.create('div', {"class":this.CSS_HEADER}, [
				title, closeLink
			]), 
			// dumb content container
			Element.create('div', {"class":this.CSS_CONTENT}) 
		])
	], this.getParent());
	
	// need to move all of this to a cssclass
	Element.addClass(frame, this.CSS_HIDDEN); 
	frame.style.visibility = "hidden";
	
	this.getFrame = function() { return frame };
	this.getDragStartEvent().addElement(this.getHeader());
	
	return this.getFrame(); 
};

Popup.prototype.getIframeShim = function() {
	return this.getFrame().childNodes[0];
};

Popup.prototype.getCanvas = function() {
	return this.getFrame().childNodes[1];
};

Popup.prototype.getHeader = function() {
	return this.getCanvas().childNodes[0];
};
Popup.prototype.getContent = function() {
	return this.getCanvas().childNodes[1];
};

Popup.prototype.clearContent = function() {
	Element.removeChildNodes(this.getContent());
};

Popup.prototype.isVisible = function() {
	return !Element.hasClass(this.getFrame(), this.CSS_HIDDEN);
};

Popup.prototype.allowOthers = function(value) {
	if (undefined !== value) {
		this._allowOthers = value;
	}
	else if (undefined === this._allowOthers) {
		this._allowOthers = false; //false by default
	}
	
	return this._allowOthers;
}

Popup.prototype.getCloseEvent = function() {
	var closeEvent = this.getEventManager().add(null, 'click', this.close, this);	
	this.getCloseEvent = function() { return closeEvent };
	return this.getCloseEvent();

};

Popup.prototype.getCloseLink = function () {
	var closeEvent = this.getCloseEvent();
	var closeLink = Element.create('a', { href: 'javascript:void(0)', className: 'closeLink' }, 'close'); 
	
	closeEvent.addElement(closeLink);
	this.getCloseLink = function() {
		
		return closeLink;
	
	};

	return this.getCloseLink();
};

Popup.prototype.getDragStartEvent = function() {
	var dragStartEvent = this.getEventManager().add(null, "mousedown", this.dragStart, this);
	this.getDragStartEvent = function() {
		return dragStartEvent;
	};
	return this.getDragStartEvent();
};

Popup.prototype.getDragStopEvent = function() {
	var dragStopEvent = this.getEventManager().add(null, "mouseup", this.dragStop, this);
	this.getDragStopEvent = function() {
		return dragStopEvent;
	};
	return this.getDragStopEvent();
};

Popup.prototype.getDragStopEvent = function() {
	var dragStopEvent = this.getEventManager().add(null, "mouseup", this.dragStop, this);
	this.getDragStopEvent = function() {
		return dragStopEvent;
	};
	return this.getDragStopEvent();
};

Popup.prototype.getDragEvent = function() {
	var dragEvent = this.getEventManager().add(null, "mousemove", this.drag, this);
	this.getDragEvent = function() {
		return dragEvent;
	};
	return this.getDragEvent();
};

Popup.prototype.getMouseOutWindow = function() {
	var dragEvent = this.getEventManager().add(null, "mouseout", function(e) {
		
		var outTarget = e.nativeEvent.toElement || e.nativeEvent.relatedTarget;
		
		if (!outTarget || "HTML" == outTarget.tagName) {	
			this.getDragStopEvent().fire();
		}
		
	}, this, null, 50);
	
	this.getMouseOutWindow = function() {
		return dragEvent;
	};
	
	return this.getMouseOutWindow();
};

Popup.prototype.getMouseOverWindow = function() {
	var dragEvent = this.getEventManager().add(null, "mouseover", function(e) {
		//console.info("mouseoverwindow", e);
	}, this);
	this.getMouseOverWindow = function() {
		return dragEvent;
	};
	return this.getMouseOverWindow();
};

Popup.prototype.onDragStop = function() {
	var dragStop = this.getEventManager().add("dragStop");
	this.onDragStop = function() {
		return dragStop;
	};
	return this.onDragStop();
};

Popup.prototype.getTitle = function () {
    var title = Element.create('h2');
	this.getTitle = function() { return title };
	return this.getTitle();
};

Popup.prototype.setTitleText = function(text) {
	this.getTitle().innerHTML = text;
};

Popup.prototype.draw = function() {
	if (this.isVisible()) {
		return;
	}
	
	if (!this.allowOthers()) {
	    for( var i = 0; i < Popup.instances.length; i++ )
	    {
	        Popup.instances[i].close();
	    }
	}
	
	var frame = this.getFrame();
	Element.removeClass(frame, this.CSS_HIDDEN);

	this.position();

	return true;
};

Popup.prototype.position = function () {
    var contentWell = Element.getXY(this.getFrame().offsetParent);
	
    var view = Element.getViewport();
	var frame = this.getFrame();

    var frameSize = Element.getSize(frame);

    var frameTop = Math.max(view.top + ( view.height / 2 ) - ( frameSize.height / 2 ), 0) - contentWell.y;
    var frameLeft = Math.max(( view.width / 2 ) - ( frameSize.width / 2 ), 0) - contentWell.x;

    Element.setXY(frame, frameLeft, frameTop);
	this.sizeShim();
	// add a class instead
    frame.style.visibility = 'visible';
};

Popup.prototype.sizeShim = function() {
	var size = Element.getSize(this.getFrame());
	Element.setSize(this.getIframeShim(), size.width, size.height);
};

Popup.prototype.close = function (e, el) {
	if(e){ e.cancel() };

	var frame = this.getFrame();
	
	if (!frame) {
		return;
	}
	
    Element.addClass(frame, this.CSS_HIDDEN);
	frame.style.visibility = "hidden";
};

Popup.prototype.drag = function(e) {
	e.cancel();
	
	this.getMouseOutWindow().clearDelayTimeouts();
	
	var coords = this.getMouseCoords(e);
	
	var x = coords.x - this.dragOffset.x;
	var y = coords.y - this.dragOffset.y;

	Element.setXY(
		this.getFrame(), x, y
	);
};

Popup.prototype.getMouseCoords = function(e) {
	var x, y;
	
	if (e.nativeEvent.pageX || e.nativeEvent.pageY) {
		x = e.nativeEvent.pageX;
		y = e.nativeEvent.pageY;
	}
	else if (e.nativeEvent.clientX || e.nativeEvent.clientY) {
		x = e.nativeEvent.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		y = e.nativeEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
	
	return {x: x, y: y};
}

Popup.prototype.dragStart = function(e, el) {
	e.cancel();
	
	this.getDragEvent().addElement(document);
	this.getDragStopEvent().addElement(document);
	
	this.getMouseOutWindow().addElement(document);
	this.getMouseOverWindow().addElement(document);
	
	var frame = this.getFrame();
	var startPos = Element.getXY(frame);
	
	// once we've dragged, position should stop being called
	this.position = function() {
		this.getFrame().style.visibility = 'visible';
	};

	var coords = this.getMouseCoords(e);	
	this.dragOffset = {
		x: coords.x - startPos.x,
		y: coords.y - startPos.y
	};
};

Popup.prototype.dragStop = function(e, el) {
	e.cancel();
	
	this.getDragEvent().removeAllElements();
	this.getDragStopEvent().removeAllElements();
	
	this.getMouseOutWindow().removeAllElements();
	this.getMouseOverWindow().removeAllElements();
	
	var frame = this.getFrame();
	var viewport = Element.getViewport();
	var size = Element.getSize(frame);
	var pos = Element.getXY(frame);
	var padding = 20;
	
	if (pos.x + this.dragOffset.x < viewport.left + padding ) {
		Element.setXY(frame, viewport.left - this.dragOffset.x + padding, null);
	}
	else if (pos.x + this.dragOffset.x > viewport.right - padding) {
		Element.setXY(frame, viewport.right - this.dragOffset.x - padding, null);
	}
	
	if (pos.y + this.dragOffset.y < viewport.top + padding) {
		Element.setXY(frame, null, viewport.top - this.dragOffset.y + padding);
	}
	else if (pos.y + this.dragOffset.y > viewport.bottom) {
		Element.setXY(frame, null, viewport.bottom - this.dragOffset.y - padding);
	}
	
	this.onDragStop().fire(Element.getXY(this.getFrame()));
};

/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/MouseHover.js
*/
function MouseHover() {
	this.eventManager = new EventManager();
};

MouseHover.prototype.CSS_MOUSE_HOVER = "mouseHover";
MouseHover.prototype.CSS_CONTENT = "mouseHoverContent";
MouseHover.prototype.CSS_HIDDEN = "wsodHidden";

MouseHover.prototype.SHOW_EVENT = "mouseHoverShow";
MouseHover.prototype.HIDE_DELAY = 70;
//MouseHover.prototype.SHOW_DELAY = 100;
MouseHover.prototype.MARGIN = 10;

MouseHover.prototype.addTarget = function(el) {
	this.getMouseOverEvent().addElement(el);
};
MouseHover.prototype.removeTarget = function(el) {
	this.getMouseOverEvent().removeElement(el);
};

MouseHover.prototype.isMovable = function(isMovable) {
	if (undefined !== isMovable) {
		this._isMovable = isMovable;
		
		if (!this.isMovable()) {
			this.addTarget(this.getContainer());
		}
		else {
			this.removeTarget(this.getContainer());
		}
	}
	else if (undefined === this._isMovable) {
		// true by default
		this._isMovable = true;
	}
	
	return this._isMovable;
}

MouseHover.prototype.attachStopEvents = function(el) {
	var e = this.getMouseOutEvent();
	e.addElement([el, document]);
	
	if (!this.isMovable()) {
		e.addElement(this.getContainer());
	}
};

MouseHover.prototype.attachMoveEvents = function(el) {
	if (!this.isMovable()) {
		return;
	}
	
	var e = this.getMouseMoveEvent();
	e.addElement([document]);
};

MouseHover.prototype.getMouseOverEvent = function() {
	var e = this.eventManager.add(null, "mouseover", this.show, this);
	this.getMouseOverEvent = function() { return e; };
	return this.getMouseOverEvent();
};

MouseHover.prototype.getMouseOutEvent = function() {
	var e = this.eventManager.add(null, "mouseout", this.hide, this, null, this.HIDE_DELAY);
	this.getMouseOutEvent = function() { return e; };
	return this.getMouseOutEvent();
};

MouseHover.prototype.getMouseMoveEvent = function() {
	var e = this.eventManager.add(null, "mousemove", this.move, this);
	this.getMouseMoveEvent = function() { return e; };
	return this.getMouseMoveEvent();
};

MouseHover.prototype.getShowEvent = function() {
	var e = this.eventManager.add(this.SHOW_EVENT);
	this.getShowEvent = function() { return e; };
	return this.getShowEvent();
};

MouseHover.prototype.getParent = function() {
	var el = Element.get("wsodPop") ? Element.get("wsodPop") : Element.create("div", {id: "wsodPop"}, null, document.body);
	this.getParent = function() { return el; };
	return this.getParent();
};

MouseHover.prototype.setParent = function(el) {
	this.getParent = function() { return el; };
};

MouseHover.prototype.getCSS = function() { return ""; }
MouseHover.prototype.setCSS = function(c) {
	this.getCSS = function() {
		return " " + c;
	}
}

MouseHover.prototype.getText = function() { return ""; }
MouseHover.prototype.setText = function(t) {
	this.getText = function() {
		return t;
	}
}

MouseHover.prototype.getContainer = function() {
	var el = Element.create("div", { "class":this.CSS_MOUSE_HOVER }, [
		Element.create("iframe", { src: "javascript:false;", "class":this.CSS_HIDDEN, frameborder: 0 }),
		Element.create("div", {"class":this.CSS_CONTENT+this.getCSS() }, this.getText())
	]);
	Element.addClass(el, this.CSS_HIDDEN);
	Element.addChild(this.getParent(), el);
	
	this.getContainer = function() { return el; };
	return this.getContainer();
};

MouseHover.prototype.getIframeShim = function() {
	return this.getContainer().childNodes[0];
};

MouseHover.prototype.getContent = function() {
	return this.getContainer().childNodes[1];
};

MouseHover.prototype.clearContent = function() {
	Element.removeChildNodes(this.getContent());
};

MouseHover.prototype.setCurrentTarget = function(el) {
	
	this.getCurrentTarget = function() { return el; };
	
};

MouseHover.prototype.getCurrentTarget = function() {
	return null;
};

MouseHover.prototype.getFader = function() {
	var fader = new Fader();
	fader.FRAME_TIME=3;
	
	this.getFader = function() {
		return fader;
	};
	
	return this.getFader();
};

MouseHover.prototype.show = function(e, el) {
	this.getMouseOutEvent().clearDelayTimeouts();
	
	if (el == this.getCurrentTarget() || (!this.isMovable() && el == this.getContainer())) {
		return;
	}
	
	this.hide();
	this.setCurrentTarget(el);
	this.getShowEvent().fire(el);
	
	var container = this.getContainer();
	
	Element.setStyle(container, "visibility: hidden;");
	Element.removeClass(container, this.CSS_HIDDEN);
	
	this.sizeAndPosition(e);
	
	Element.setStyle(container, "visibility: visible;");
	
	this.getFader().fadeIn(this.getContainer()).addListener(
		function() {
			Element.removeClass(this.getIframeShim(), this.CSS_HIDDEN);
		}, 
	this);
	
	this.attachMoveEvents();
	this.attachStopEvents(el);
};

MouseHover.prototype.sizeAndPosition = function(e) {
	var container = this.getContainer();
	var pos = Element.getXY(container);
	
	this.parentOffset = Element.getXY(container.offsetParent) || { x: 0, y: 0 };
	this.viewport = Element.getViewport();
	this.size = Element.getSize(container);
	
	Element.setSize(this.getIframeShim(), this.size.width, this.size.height);
	
	this.move(e || {
		nativeEvent: {
			clientX: pos.x - this.viewport.left - this.MARGIN,
			clientY: pos.y - this.viewport.top - this.MARGIN
		}
	});
};

MouseHover.prototype.move = function(e) {
	
	if (e.nativeEvent.pageY == e.nativeEvent.clientY) {
		// safari reports clientX/Y incorrectly, either this is safari, or we are not scrolled
		var x = e.nativeEvent.clientX - this.parentOffset.x + this.MARGIN;
		var y = e.nativeEvent.clientY - this.parentOffset.y + this.MARGIN;
	}
	else {
		var x = e.nativeEvent.clientX - this.parentOffset.x + this.viewport.left + this.MARGIN;
		var y = e.nativeEvent.clientY - this.parentOffset.y + this.viewport.top + this.MARGIN;
	}
	

	var right = x + this.size.width;
	var bottom = y + this.size.height;
	
	if (right > this.viewport.right - this.MARGIN) {
		x -= (right - this.viewport.right + this.MARGIN); 
	}
	
	if (bottom > this.viewport.bottom - this.MARGIN) {
		y -= (bottom - this.viewport.bottom + this.MARGIN);
	}
	
	Element.setXY(this.getContainer(), x, y);
};

MouseHover.prototype.hide = function(e) {
	//ie mouseout event bubbling fix
	if(e){
		var el = this.getContainer();
		var reltg = (e.nativeEvent.relatedTarget) ? e.nativeEvent.relatedTarget : e.nativeEvent.toElement; 						
		if(reltg){
		    while (reltg != el && reltg.nodeName != 'HTML')
			    reltg = reltg.parentNode		
		    if (reltg==el)
				return;			
		}
	}
	this.getMouseOverEvent().clearDelayTimeouts();
	
	this.getFader().fadeOut(this.getContainer()).addListener(
		function() {
			this.getFader().clearFadeProperties(this.getContainer());	
			Element.addClass(this.getIframeShim(), this.CSS_HIDDEN);
			Element.addClass(this.getContainer(), this.CSS_HIDDEN);		
		}, 
	this);
	
	this.setCurrentTarget(null);
	
	this.getMouseOutEvent().removeAllElements();
	this.getMouseMoveEvent().removeAllElements();
};
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/MouseHover.Symbol.js
*/
MouseHover.Symbol = function() {
	MouseHover.Symbol.Super(this);
};

MouseHover.Symbol.Extend(MouseHover);

MouseHover.Symbol.init = function() {
	
	var els = Element.parseSelector("a[" + this.prototype.ATTR_SYMBOL + "]", Element.get("wsod"));
	
	if (!els.length) {
		return;
	}
	
	var mhs = new MouseHover.Symbol();
	mhs.addTarget(els);	
	mhs.setParent(Element.create("div", {id:this.prototype.ID}, null, mhs.getParent()));
	
	mhs.getCache();
	mhs.getShowEvent().addListener({
		context: mhs,
		handler: mhs.requestContent
	});	
};

MouseHover.Symbol.prototype.ID = "wsodSymbolHover";
MouseHover.Symbol.prototype.ATTR_SYMBOL = "mousehoversymbol";

MouseHover.Symbol.prototype.getContentBuffer = function() {
	var cb = new ContentBuffer();
	this.getContentBuffer = function() {
		return cb;
	};
	return this.getContentBuffer();
};

MouseHover.Symbol.prototype.getCache = function(symbol) {
	var cache = {};
	this.getCache = function(symbol) {
		if (!symbol) {
			return;
		}
		
		return cache[symbol];
	};
	this.setCache = function(symbol, value) {
		if (!symbol) {
			return;
		}
		cache[symbol] = value;
		return this.getCache(symbol);
	};
	
	return this.getCache(symbol);
};

MouseHover.Symbol.prototype.requestContent = function(type, el) {
	var symbol = el.getAttribute(this.ATTR_SYMBOL);
	if (this.getCache(symbol)) {
		this.updateContent(symbol, this.getCache(symbol));
		return;
	}
	
	this.clearContent();
	Element.create("div", {"class":"wsodLoading"}, null, this.getContent());
	
	this.getContentBuffer().load({
		url: "/ft/markets/data/getSymbolHover.asp",
		data: {
			s: symbol,
			callback: "updateContent"
		},
		contentType: "text/javascript",
		context: this
	});
};

MouseHover.Symbol.prototype.updateContent = function(symbol, content) {
	var cache = this.setCache(symbol, content);
	
	if (this.getCurrentTarget() && symbol != this.getCurrentTarget().getAttribute(this.ATTR_SYMBOL)) {
		this.getShowEvent().fire(this.getCurrentTarget());
		return;
	}
	
	this.getContent().innerHTML = cache;
	this.sizeAndPosition();
};
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/SymbolSearch.js
*/
/* this file to be pulled in via a script tag at ft.com 
 * we should set max-age cache header to about an hour on this dir
 * 
 */

if (!window.WSDOM) {
	WSDOM = new function() {
		var loadedClasses = {};
		var usingReferences = [];

		this.defineClass = function(className, superClass, constructor) {
			loadedClasses[className] = constructor;

			if (null != superClass) {
				loadedClasses[className].Extend(superClass);
			}

			// both classes and instances should have references to their names
			loadedClasses[className].prototype.getClassName = function() {
				return className;
			};
			loadedClasses[className].getClassName = loadedClasses[className].prototype.getClassName;

			return loadedClasses[className];
		};

		this.loadClass = function(className) {
			var classDef = parseClassName(className);

			var o = this.getClass(classDef.className);
			if (o) {
				this[o.getClassName()] = o;
				this[o.getClassName()].prototype.namespace = classDef.namespace;
				this[o.getClassName()].prototype.version = classDef.version;
			};
		};

		this.loadSingleton = function(className) {
			var classDef = parseClassName(className);

			var o = this.getClass(classDef.className);
			if (o) {
				this[o.getClassName()] = new o();
				this[o.getClassName()].namespace = classDef.namespace;
				this[o.getClassName()].version = classDef.version;
			};
		};

		this.getClass = function(className) {
			return loadedClasses[className];
		};

		this.getLoadedClasses = function() {
			return loadedClasses;
		};

		this.using = function(originatingClassName, className) {
			usingReferences.push({originatingClassName:originatingClassName, className:className});
		}


		this._processUsingReferences = function() {

			var usingErrors = false;
			for (var x = 0; x < usingReferences.length; x++) {

				var originatingClassName = usingReferences[x].originatingClassName;
				var className = usingReferences[x].className;
				var classDef = parseClassName(className);

				if (!this[classDef.className]) {
					if (this.Console) {
						this.Console.warn("Missing class definition for " + className + ".  Called from " + originatingClassName + ".");
					};
					usingErrors = true;
				} else if (this[classDef.className].version != classDef.version && (!this[classDef.className].prototype || this[classDef.className].prototype.version != classDef.version)) {
					if (this.Console) {
						this.Console.warn("Version incompatibility for loaded class, " + classDef.className + "." + this[classDef.className].version + ", versus requested class, version " + classDef.version + ".  Called from " + originatingClassName + ".");
					};
					usingErrors = false;
				};

			};
			if (!usingErrors && this.Console) {
				this.Console.log("WSDOM Framework loaded successfully.");
			};
		};




		/* Light-weight 'onload' for management of 'using' statements */
		this._onload = function() {
			var element = window;
			var eventType = "load";
			var fnHandler = this._processUsingReferences.Context(this);

			if (element.addEventListener) {
				// firefox
				element.addEventListener(eventType, fnHandler, false);
			}
			else if (element.attachEvent) {
				// ie
				element.attachEvent("on" + eventType, fnHandler);
			};
		};
		this._onload();


		function parseClassName(className) {
			var tokens = className.split('.');

			var classDef = {
				namespace:tokens[0],
				className:tokens[1],
				version:tokens[2]
			};

			return classDef;
		};



		this.identity = function(x) { return x };

	}();

	function capitalizeString ( st ) {
			
		st = st.split(/\s+/);
		
		var i	  	= 0,
			len   	= st.length,
			chunk 	= new Array(),
			noAlter = /^(the|or|and|to)$/;
			
		for(; i < len; i++) {
			
			if(noAlter.test(st[i]) && i) {
				
				chunk.push(st[i], ' ');
				continue;
			}
			
			chunk.push(
				 st[i].slice(0,1).toUpperCase()
				,st[i].slice(1)
				,' '
			);
		}
		
		return chunk.join('');
	};

	WSDOM.using("WSDOM.Element.3", "WSDOM.Events.2");
	WSDOM.defineClass("Element", null, Element_class);
	WSDOM.loadSingleton("WSDOM.Element.3");

	WSDOM.using("WSDOM.Serializer.3", "WSDOM.Console.1");
	WSDOM.defineClass("Serializer", null, Serializer);
	WSDOM.loadSingleton("WSDOM.Serializer.3");

	WSDOM.defineClass("Events", null, EventManager);
	WSDOM.loadSingleton("WSDOM.Events.3");
}
 
 
var SymbolSearch = function(elForm) {
	
	this.localCache = {};
	this.eventManager = new EventManager();
	this.query = "";
	this.issueType = "";
	
	this.setDestinationURL(this.DESTINATION_URL);
	this.setRequestURL(this.REQUEST_URL);
	this.setFinderURL(this.FINDER_URL);
	
	if (elForm || WSDOM.Element.get(this.DEFAULT_FORM_ID)) {
		// DOM has loaded
		this.setForm(elForm);
	}
	else {
		this.eventManager.add(window, "load", function() { this.setForm(elForm) }, this);
	}
};

SymbolSearch.prototype.DEFAULT_FORM_ID = "wsod-symbolSearch";
SymbolSearch.prototype.FORM_INPUT_SELECTOR = "input[name='s'],input[name='query']";

SymbolSearch.prototype.REQUEST_URL = "/ft/symbolSearch/data/getSymbols.asp";
SymbolSearch.prototype.DESTINATION_URL = "";
SymbolSearch.prototype.FUND_DESTINATION_URL = "http://funds.ft.com/factsheet.aspx?mexid=";
SymbolSearch.prototype.FINDER_URL = "/ft/markets/finder.asp";
SymbolSearch.prototype.KEY_PRESS_WAIT = 0;

SymbolSearch.prototype.CSS_HIDDEN = "symbolSearchHidden";
SymbolSearch.prototype.CSS_SELECTED = "selected";
SymbolSearch.prototype.CSS_RESULTS = "symbolSearch";
SymbolSearch.prototype.CSS_ISSUE_NAME = "issueName";
SymbolSearch.prototype.CSS_GROUP_END = "symbolSearchGroupEnd";
SymbolSearch.prototype.CSS_FLAG = "wsod-flag";
SymbolSearch.prototype.CSS_FLAG_COUNTRY = "flag-";
SymbolSearch.prototype.CSS_MORE_LINK = "more";
SymbolSearch.prototype.CSS_MORE_SEARCH_RESULTS = "searchResultsMoreLink";

SymbolSearch.prototype.ATTR_NO_RESULTS = "noresults";

SymbolSearch.prototype.KEY_CODE_UP = 38;
SymbolSearch.prototype.KEY_CODE_DOWN = 40;
SymbolSearch.prototype.KEY_CODE_ESC = 27;
SymbolSearch.prototype.KEY_CODE_ENTER = 13;

SymbolSearch.prototype.invalidChars = /\s/g;
SymbolSearch.prototype.countryPrefix = /^[a-z]{2}\:/i;

SymbolSearch.prototype.setForm = function(elForm) {
	this.clearInputEventHandlers();
	
	this.elForm = elForm || WSDOM.Element.get(this.DEFAULT_FORM_ID);
	this.elInput = WSDOM.Element.parseSelector(this.FORM_INPUT_SELECTOR, this.elForm, "first");
	
	this.addInputEventHandlers();
};

SymbolSearch.prototype.addInputEventHandlers = function() {
	this.eventManager.add(this.elInput, "keyup", this.search, this, null, this.KEY_PRESS_WAIT);
	this.eventManager.add(this.elInput, "click", function(e) {
		e.cancel();
	});
};

SymbolSearch.prototype.clearInputEventHandlers = function() {
	if (this.elInput) {
		this.eventManager.remove(this.elInput);
	}
};

SymbolSearch.prototype.addResultEvents = function(noResults) {
	this.selectedRow = -1;
	
	if (!noResults) {
		this.getOnNavResults().addElement(this.elInput);
		this.getOnHoverResults().addElement(this.elResultRows);
		this.getOnClickResults().addElement(this.elResultRows);
	}
	
	this.getOnHideResults().addElement(document);
	this.getOnSubmitResults().addElement(this.elInput);
	this.getOnChangeInput(true).addElement(this.elInput);
	
	if (this.moreResultsPopupMode() && this.elMoreResults){
		this.getOnMoreLinkResults().addElement(this.elMoreResults);
	}	
};

SymbolSearch.prototype.removeResultEvents = function() {	
	this.getOnNavResults().removeAllElements();
	this.getOnHoverResults().removeAllElements();
	this.getOnClickResults().removeAllElements();
	this.getOnHideResults().removeAllElements();
	this.getOnSubmitResults().removeAllElements();
	this.getOnChangeInput(true).removeAllElements();
	this.getOnMoreLinkResults().removeAllElements();
};

SymbolSearch.prototype.attachResizeEvent = function() {
	WSDOM.Events.add(window, "resize", this.repositionResults, this);
}

SymbolSearch.prototype.repositionResults = function() {
	if (this.resizeTimeout) { clearTimeout(this.resizeTimeout); }
	
	var ss = this;

	this.resizeTimeout = setTimeout(function() {
		if (ss.localCache[ss.query + ss.issueType]) {
			ss.drawResults(ss.localCache[ss.query + ss.issueType]);
		}
	}, 200);
}

SymbolSearch.prototype.getOnChangeInput = function(cancelNative) {
	var eventSourceCancel = this.eventManager.add(null, "change", this.delayChangeEvent, this, true);
	var eventSourcePassThrough = this.eventManager.add(null, "change", this.delayChangeEvent, this);
	
	this.getOnChangeInput = function(cancelNative) {
		if (cancelNative) {
			return eventSourceCancel;
		}
		return eventSourcePassThrough;
	};
	
	return this.getOnChangeInput(cancelNative);
};

SymbolSearch.prototype.delayChangeEvent = function(e, el, cancelNative) {
	if (cancelNative) {
		e.cancel();
	}
};

SymbolSearch.prototype.getOnNavResults = function() {
	var eventSource = this.eventManager.add(null, "keydown", this.navigate, this);
	this.getOnNavResults = function() {
		return eventSource;
	};
	
	return this.getOnNavResults();
};

SymbolSearch.prototype.getOnHoverResults = function() {
	var eventHandler = function(e, el) {
		this.highlightRow(el.rowIndex);

	};
	var eventSource = this.eventManager.add(null, "mouseover", eventHandler, this);
	this.getOnMouseOverResults = function() {
		return eventSource;
	};
	
	return this.getOnMouseOverResults();
};
SymbolSearch.prototype.getOnHideResults = function() {
	var eventSource = this.eventManager.add(null, "click", this.clearResults, this);

	this.getOnHideResults = function() {
		return eventSource;
	};
	
	return this.getOnHideResults();
};
SymbolSearch.prototype.getOnClickResults = function() {
	var eventSource = this.eventManager.add(null, "click", this.selectResult, this);
	this.getOnClickResults = function() {
		return eventSource;
	};
	
	return this.getOnClickResults();
};
SymbolSearch.prototype.getOnSubmitResults = function() {
	var eventSource = this.eventManager.add(null, "keypress", this.selectResult, this);
	this.getOnSubmitResults = function() {
		return eventSource;
	};
	
	return this.getOnSubmitResults();
};
SymbolSearch.prototype.setRequestor = function(requestor) {
	this.requestor = requestor;
};
SymbolSearch.prototype.setDestinationURL = function(URL) {
	this.destinationURL = URL;
};

SymbolSearch.prototype.setRequestURL = function(URL) {
	this.requestURL = URL;
};
SymbolSearch.prototype.setFinderURL = function(URL) {
	this.finderURL = URL;
};

SymbolSearch.prototype.highlightText = function(c) {
	var sTermArray = String(this.query).replace(this.countryPrefix, "").split(" ");
	var sTermLen = sTermArray.length;
	
	if (c.n.indexOf(" ")) {
		var coName = c.n.split(" ");
		var coNameLen = coName.length;
	} else {
		var coName = c.n;
		var coNameLen = 1;
	}
	
	if(sTermLen == 1){
		var replacement = '<b>$1</b>';
		var re = new RegExp("\\b(" + sTermArray + ")", "gi");
		c.d = String(c.s).replace(re, replacement);
		c.n = String(c.n).replace(re, replacement);
	} else {
		for (var i = 0; i < coNameLen; i++) {
			var coNamePart = coName[i];
			if(!coNamePart.length){
				continue;
			}
			for(var z = 0; z < sTermLen; z++){
				var term = sTermArray[z].replace(/\s/g, "");
				var termLen = term.length;
				if (termLen && term.toLowerCase() == coNamePart.toLowerCase().substring(0, termLen)) {
					coName[i] = '<b>' + coNamePart.substring(0, termLen) + '</b>' + coNamePart.substring(termLen);
					z = sTermLen;
				}
			}
			
			c.n = coName.join(' ');
		}
	}
	
	return c;
};

SymbolSearch.prototype.ISSUE_TYPES = {
	ALL: "",
	EQ: "EQ",
	ETF: "ETF",
	MF: "MF",
	IN: "IN"
};

SymbolSearch.prototype.setIssueType = function(type) {
	this.issueType = type;
};

SymbolSearch.prototype.search = function(e, el) {
	if (el.value == this.query) {
		return;
	}	

	else if (!String(el.value).replace(this.invalidChars, "")) {
		this.query = el.value;
		this.clearResults();

	}
	else {
		this.abortActiveRequests();
		this.query = el.value;
		if (this.localCache[this.query + this.issueType]) {
			this.drawResults(this.localCache[this.query + this.issueType]);

		}
		else {
			this.requestor.load({
				url: this.requestURL,
				contentType: "text/javascript",
				data: { q: this.query, issueType: this.issueType, callback: "handleResults", context: "this" },
				context: this
			});
		}
	}	

};

SymbolSearch.prototype.handleResults = function(query, results, showMoreLink) {
	var cachedNodes = [];
	var elTable = WSDOM.Element.create("table");
	
	for (var i=0,group; i<results.length; i++) {
		group = results[i];
		if (group.length) {
			var elTbody = WSDOM.Element.create("tbody"); 
			
			for (var j=0,c; j<group.length; j++) {
				c = this.highlightText(group[j]);
				
				var elFlag = WSDOM.Element.create("div");
				WSDOM.Element.addClass(elFlag, this.CSS_FLAG);
				WSDOM.Element.addClass(elFlag, this.CSS_FLAG_COUNTRY + c.c);
		
				var elRow = WSDOM.Element.create("tr", { symbol: c.s, isfund: c.f }, [
					WSDOM.Element.create("td", { "class": this.CSS_ISSUE_NAME }, c.n),
					WSDOM.Element.create("td", null, elFlag),
					WSDOM.Element.create("td", null, c.d)
				], elTbody);
				
				if (group.length-1 == j && (results.length -1 != i || showMoreLink)) {
					WSDOM.Element.addClass(elRow, this.CSS_GROUP_END);
				}

			}
			WSDOM.Element.addChild(elTable, elTbody);
		}
	}
	
	if (showMoreLink) {
		WSDOM.Element.create("tbody", null, [
			WSDOM.Element.create("tr", { "class": this.CSS_MORE_LINK }, [
				WSDOM.Element.create("td", { "colspan":3 }, [
					WSDOM.Element.create("a", { "class":this.CSS_MORE_SEARCH_RESULTS, href: this.moreResultsPopupMode() ? "#" : this.buildMoreLink() }, "Additional matches for " + query + " &gt;")
				])
			])
		], elTable);	
	}
	
	if (!elTable.childNodes.length) {
		WSDOM.Element.create("tbody", null, [
			WSDOM.Element.create("tr", { "class": this.CSS_GROUP_END }, [
				WSDOM.Element.create("td", null, "No securities were found for \"<b>" + query + "</b>\".<br />Try symbol lookup for a more advanced search.")
			])
		], elTable);
		elTable.setAttribute(this.ATTR_NO_RESULTS, "true");
	}
	
	cachedNodes.push(elTable);
	this.localCache[query + this.issueType] = cachedNodes;
	
	this.drawResults(cachedNodes);
	
};

SymbolSearch.prototype.createResultsContainer = function() {
	this.elResults = WSDOM.Element.create("div", { "class": this.CSS_HIDDEN }, null, document.body);
	WSDOM.Element.addClass(this.elResults, this.CSS_RESULTS);
};


SymbolSearch.prototype.drawResults = function(cachedNodes) {
	this.clearResults();
	
	if (!this.elResults) {
		this.createResultsContainer(); 

	}

	var pos = WSDOM.Element.getXY(this.elInput);
	var size = WSDOM.Element.getSize(this.elInput);
	
	WSDOM.Element.setXY(this.elResults, pos.x, pos.y + size.height);
	
	WSDOM.Element.removeClass(this.elResults, this.CSS_HIDDEN);
	for (var i=0; i<cachedNodes.length; i++) {
		WSDOM.Element.addChild(this.elResults, cachedNodes[i]);
	}
	this.elResultRows = WSDOM.Element.parseSelector("tr", this.elResults);
	this.elMoreLink = WSDOM.Element.parseSelector("tr." + this.CSS_MORE_LINK + " a", this.elResults, "first");
	this.elMoreResults = WSDOM.Element.parseSelector("a.searchResultsMoreLink", this.elResults, "first");
	
	this.addResultEvents(cachedNodes[0].getAttribute(this.ATTR_NO_RESULTS));
	
	WCH.Apply(this.elResults, null, true);
};


SymbolSearch.prototype.clearResults = function() {
	if (!this.elResults) {
		return;

	}
	if (this.elResultRows && this.elResultRows.length) {
		WSDOM.Element.removeClass(this.elResultRows, this.CSS_SELECTED);
	}
	WSDOM.Element.addClass(this.elResults, this.CSS_HIDDEN);
	WSDOM.Element.removeChildNodes(this.elResults);
	this.removeResultEvents();
	WCH.Discard(this.elResults);
};

SymbolSearch.prototype.buildMoreLink = function() {
	// var URL = this.finderURL + "?query=" + this.query;
	var URL = this.finderURL + "?time=" + new Date().getTime() + "&query=" + escape(this.query);

	if (this.issueType) {
		if ('IN' == this.issueType) {
			URL += "&view=markets&issueType=" + this.issueType;
		}
		else {
			URL += "&issueType=" + this.issueType;
		}
	}
	
	return URL;
};

SymbolSearch.prototype.navigate = function(e) {
	switch (e.nativeEvent.keyCode) {
		case this.KEY_CODE_DOWN :
			e.cancel();
			var rowIdx = Math.min(this.selectedRow + 1, this.elResultRows.length-1);
			this.highlightRow(rowIdx);
			break;
		
		case this.KEY_CODE_UP :
			e.cancel();
			var rowIdx = Math.max(this.selectedRow - 1, -1);
			this.highlightRow(rowIdx);
			break;
		
		case this.KEY_CODE_ESC :
			e.cancel();
			this.clearResults();
			break;
	}

};

SymbolSearch.prototype.highlightRow = function(rowIdx) {
	if (this.selectedRow != rowIdx) {
		if (this.elResultRows[this.selectedRow]) {
			WSDOM.Element.removeClass(this.elResultRows[this.selectedRow], this.CSS_SELECTED);		
		}
		if (this.elResultRows[rowIdx]) {

			WSDOM.Element.addClass(this.elResultRows[rowIdx], this.CSS_SELECTED)
		}
		
		this.selectedRow = rowIdx;
	}

};

SymbolSearch.prototype.selectResult = function(e) {
	if ("click" == e.nativeEvent.type || this.KEY_CODE_ENTER == e.nativeEvent.keyCode) {
		e.cancel();

		if (this.selectedRow == -1) {
			if (this.elResultRows && 1 == this.elResultRows.length) {
				// only one result, set it as selected
				this.selectedRow = 0;
			}
			else {
				// multiple results, just submit the form
				this.go(this.elInput.value);
				return;
			}
		}
		else {
			if (WSDOM.Element.hasClass(this.elResultRows[this.selectedRow], this.CSS_MORE_LINK)) {
				// more link clicked
				window.location = this.elMoreLink.href;
				return;
			}
		}
		
		// go to selected row
		this.go(
			this.elResultRows[this.selectedRow].getAttribute("symbol"), 
			(this.elResultRows[this.selectedRow].getAttribute("isfund") == "1")
		);
		
	}
};

SymbolSearch.prototype.setInputValue = function(value) {
	this.elInput.value = value;
	
	var onChangeInput = this.getOnChangeInput();
	onChangeInput.addElement(this.elInput);
	onChangeInput.fire();
	onChangeInput.removeAllElements();
};

SymbolSearch.prototype.go = function(symbol, isFund) {
	if (symbol) {
		this.query = symbol;
		this.setInputValue(symbol);
	}
	
	if (isFund) {
		window.location = this.FUND_DESTINATION_URL + this.query;
	}
	else {
		this.elForm.action = this.destinationURL;
		this.elForm.submit();
	}
	
	this.clearResults();
	
};

SymbolSearch.prototype.abortActiveRequests = function() {
	this.requestor.abortRequests();

};

// The following functions have been added to allow the "more results" piece to load in a popup rather than a separate page.
// This has a dependancy on /resources/client/markets/Finder.asp

SymbolSearch.prototype.MORE_RESULTS_URL = "/ft/markets/data/getFinderResults.asp?charts=true";

SymbolSearch.prototype.moreResultsPopupMode = function(enable) {
	var mode = enable ? enable : false;
	
	this.moreResultsPopupMode = function() {
		return mode;
	}
	
	return this.moreResultsPopupMode();
}

SymbolSearch.prototype.getOnMoreLinkResults = function() {
	var eventSource = this.eventManager.add(null, "click", this.getMoreResults, this);
	this.getOnMoreLinkResults = function() {
		return eventSource;
	};
	return this.getOnMoreLinkResults();
};

SymbolSearch.prototype.getMoreResults = function(e, el) {
	e.cancel();
	
	//this.showLoading();
	this.getBuffer().abortRequests();
	this.getBuffer().load({
		url: this.MORE_RESULTS_URL,
		data: {
			params: this.getFormSerializer().serialize(this.elForm)
		},
		onload: this.moreResultsHandler,
		onerror: this.drawError,
		context: this
	});
};

SymbolSearch.prototype.getBuffer = function() {
	var cb = new ContentBuffer();
	
	this.getBuffer = function() {
		return cb;
		
	};
	
	return this.getBuffer();
};

SymbolSearch.prototype.getFormSerializer = function() {
	var fs = new FormSerializerLite();
	
	this.getFormSerializer = function() {
		return fs;
	};
	
	return this.getFormSerializer();
};

SymbolSearch.prototype.moreResultsHandler = function(cb){
	if(cb){		
		if(!this.popup)
			this.popup = new Popup();
		this.popup.allowOthers(true);
		this.popup.clearContent();
		WSDOM.Element.setHTML(this.popup.getContent(), cb.getResult());
		this.popup.getContent().setAttribute('id', 'searchResults');
		WSDOM.Element.addClass(this.popup.getContent(), 'searchResults');
		WSDOM.Element.addClass(this.popup.getFrame(), 'moreResults');		
		this.popup.setTitleText('Search Results');
		this.popup.draw();
		if(!this.finder){ this.finder = new Finder(); }
		this.clearResults();
		var callback = this.moreResultsHandlerCallback();
		if (callback) { callback(this.popup, this.popup.getContent()); }
		this.finder.initResultEvents();
	}	
}

SymbolSearch.prototype.moreResultsHandlerCallback = function(handler, context) {
	var f = context ? handler.Context(context) : handler ? handler : null;
	
	this.moreResultsHandlerCallback = function() {
		return f;
	}
	
	this.moreResultsHandlerCallback();
}
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/chart/ChartImage.js
*/
function ChartImage() 
{
	this.serializer = new Serializer();
	this.contentBuffer = new ContentBuffer();
	this.contentBuffer.debug = true;
}

ChartImage.prototype.CSS_HIDDEN = "wsodHidden";
ChartImage.prototype.URL = "/ft/chart/getChart.asp";

ChartImage.prototype.load = function(args) 
{
	this.type = args.type || "interactive";
	this.callback = args.callback || null;
	this.context = args.context || window;

	this.showLoading();

	var cht = args.settings.type || "interactive";
	var settings = (args.settings) ? this.serializer.serialize(args.settings) : "";
	var params = (args.params) ? this.serializer.serialize(args.params) : "";
	var returns = args.returns || "fileName:File.Name";
	var validateSymbol = args.validateSymbol || "";
	var minsDelayed = args.minsDelayed || "";
	var getDisclaimer = args.getDisclaimer || "";
	var getSupplementalData = args.getSupplementalData || "";
	var sessionName = args.sessionName || '';
	var sessionValue = args.sessionValue || '';
	
	this.img = Element.parseSelector("img.chartImage", this.type+"ChartImageContainer");
	
	this.contentBuffer.abortRequests();
	var connection = this.contentBuffer.load({
		url: this.URL,
		method: "post",
		contentType: "text/javascript",
		context: this,
		data: {
			cht: cht
			,settings: settings
			,params: params
			,returnVars: returns 
			,validateSymbol: validateSymbol
			,getDisclaimer: getDisclaimer
			,minsDelayed: minsDelayed
			,getSupplementalData: getSupplementalData
			,sessionName: sessionName
			,sessionValue: sessionValue
		}/*,
		onload: function() {
			this.showImage();
		}*/
	});

	return connection;
}

ChartImage.prototype.onload = function(results) {
	results = this.serializer.deserialize(results);
	
	for (var i in results) {
		this[i] = results[i];
	}
	
	this.showImage();
};

ChartImage.prototype.showImage = function() 
{
	var img = document.createElement('img');
	Events.add({element: img, type: "load", context: this, handler: this.finishLoad});
	img.src = this.fileName;
}

ChartImage.prototype.finishLoad = function() 
{
	for (var i = 0; i < this.img.length; i++) {
		this.img[i].src = this.fileName;
	}

	if (this.callback) { this.callback.apply(this.context); }
	
	this.hideLoading();
}

ChartImage.prototype.showLoading = function() 
{
	var chartSize = Element.getSize(this.type+"ChartImageContainer");
	var chartLoading = Element.parseSelector("div.chartLoading",this.type+"ChartImageContainer");
	if (chartSize.width > 0) { Element.setSize(chartLoading, chartSize.width, chartSize.height); }
	
	Element.removeClass(chartLoading, this.CSS_HIDDEN);
}

ChartImage.prototype.hideLoading = function() 
{
	Element.addClass(Element.parseSelector("div.chartLoading", this.type+"ChartImageContainer"), this.CSS_HIDDEN);
	// remember to remove the below line
	//Element.addClass(Element.parseSelector("div.chartLoading", this.type+"ChartImageContainer"), "hide");
}

ChartImage.prototype.testit = function() {
	alert('here');
}
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/DataDefinitions.js
*/
function DataDefinitions () {
	DataDefinitions.Super(this);
	this.definitions = null;
};
DataDefinitions.Extend(Popup);

DataDefinitions.prototype.getBuffer = function() {
	var cb = new ContentBuffer();
	this.getBuffer = function() { return cb; };
	
	return this.getBuffer();
};

DataDefinitions.prototype.setDefinitionSet = function(set) {
	this.definitionSet = set;
};

DataDefinitions.prototype.requestURL = "/ft/resources/buffer/getDataDefinitions.asp";

DataDefinitions.prototype.getDefinitions = function() {
	this.getBuffer().load({
		url: this.requestURL,
		data: {
			view: this.definitionSet
		},
		onload: this.updateContent,
		context: this
	})
};

DataDefinitions.prototype.draw = function() {
	
	if (this.isVisible()) {		
		return;
	}
	
	if (!this.definitions) {
		this.setTitleText("Data Definitions - " + this.definitionSet);
		Element.addClass(this.getFrame(), "dataDefinitions");
		this.getDefinitions();
		Element.addChild(this.getContent(), Element.create("p", null, "Loading definitions for data items displayed on this page."));
	}
	
	DataDefinitions.Super(this, "draw");
};

DataDefinitions.prototype.updateContent = function(response) {
	this.clearContent();
	this.definitions = response.getResult();
	this.getContent().innerHTML = this.definitions;
};
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/SortableTable.js
*/
function SortableTable(table,rowOfHead)
{
	var rThead = Element.parseSelector("thead", table);
	this.list = [];

	for (var h=0; h<rThead.length; h++)
	{
		var tbody = Element.parseSelector("+tbody",rThead[h],"first");
		if (tbody) {
			this.list.push(new _SortableTable(rThead[h],tbody,rowOfHead));
		}
	}
}
SortableTable.prototype.init = function(table,rowOfHead)
{
	return new SortableTable(table, rowOfHead);
}

function _SortableTable(tHead, tBody, rowOfHead) {
	if (tHead && tBody) {
		this.eventManager = new EventManager();
		this.init(tHead, tBody, rowOfHead);
	}
};

_SortableTable.prototype.init = function(tHead, tBody, rowOfHead) {

	this.table = tHead && tHead.parentNode
		|| this.tHead && this.tHead.parentNode
		|| this.table;

	this.thead = tHead; //Element.parseSelector("thead", this.table, "first");
	this.tbody = tBody; //Element.parseSelector("tbody", this.table, "first");

	this.colHeads = Element.parseSelector("th", this.thead);
	this.sortableColHeads = Element.parseSelector("th[" + this.ATTR_DEFAULT_SORT_DIR + "]", this.thead);
	if(this.thead.WSOD_clones) {
		for(var i = 0; i < this.thead.WSOD_clones.length; i++) {
			this.sortableColHeads = this.sortableColHeads.concat(Element.parseSelector("th[" + this.ATTR_DEFAULT_SORT_DIR + "]", this.thead.WSOD_clones[i]));
		}
	}
	this.rows = Element.parseSelector("tr", this.tbody);

	this.lastSort = -1; // necessary?

	this.rowOfHead = rowOfHead || this.rowOfHead || 0;
	this.addEventHandlers();

};

_SortableTable.prototype.ATTR_DEFAULT_SORT_DIR = "sortdir";
_SortableTable.prototype.ATTR_USE_SORT_FIELD = "usesortfield";
_SortableTable.prototype.ATTR_SORT_VALUE = "sortval";
_SortableTable.prototype.CSS_SORTED = "sorted";
_SortableTable.prototype.CSS_LEFT_ALIGN = "left";
_SortableTable.prototype.CSS_SORTED_ASC = "asc";
_SortableTable.prototype.CSS_SORTED_DESC = "desc";

_SortableTable.prototype.addEventHandlers = function() {
	if (this.sortEvents) {
		this.sortEvents.removeAllElements();
	}

	this.sortEvents = this.eventManager.add(this.sortableColHeads, "click", this._sort, this);
};

_SortableTable.prototype._sort = function(e, el) {
	var addClass, replaceClass;
	
	var getCellIndex = function(el) {
		var row = el.parentNode;
		for(var i = 0; i < row.cells.length; i++) 
			if(row.cells[i] == el) return i;
		return -1;
	};
	var getOriginalCell = function(el) {
		return getRowGroup(el).WSOD_original.rows[0].cells[getCellIndex(el)];
	};
	var getRowGroup = function(el){
		return el.parentNode.parentNode;
	};
	var getCellClones = function(el) {
		var cellIndex = getCellIndex(el);
		var clones = [], row;
		for(var i = 0; i < getRowGroup(el).WSOD_clones.length; i++) {
			row = getRowGroup(el).WSOD_clones[i].rows[0];
			if (row.cells.length > cellIndex) {
				clones.push(row.cells[cellIndex]);
			}
		}
		return clones;
	};
	
	if (getRowGroup(el).WSOD_original) {
		el = getOriginalCell(el);
	}
	
	if (el.parentNode.parentNode.WSOD_original || el.parentNode.parentNode.WSOD_clones) {
		addClass = function(el, className) {
			Element.addClass(el, className);
			Element.addClass(getCellClones(el), className);
		};
		removeClass = function(el, className) {
			Element.removeClass(el, className);
			Element.removeClass(getCellClones(el), className);
		};
		replaceClass = function(el, oldClass, newClass) {
			Element.replaceClass(el, oldClass, newClass);
			Element.replaceClass(getCellClones(el), oldClass, newClass);
		};
	} else {
		addClass = function(el, className) {
			Element.addClass(el, className);
		};
		removeClass = function(el, className) {
			Element.removeClass(el, className);
		};
		replaceClass = function(el, oldClass, newClass) {
			Element.replaceClass(el, oldClass, newClass);
		};
	}

	if(el.cellIndex == this.lastSort || Element.hasClass(el, this.CSS_SORTED)) {

		if (Element.hasClass(el, this.CSS_SORTED_ASC)) {
			replaceClass(el, this.CSS_SORTED_ASC, this.CSS_SORTED_DESC);
		} else {
			replaceClass(el, this.CSS_SORTED_DESC, this.CSS_SORTED_ASC);
		}

		this.rows.reverse();

	} else {

		for (var i=0; i<this.colHeads.length; i++) {
			removeClass(this.colHeads[i], this.CSS_SORTED);
		}

		this._sortRows(el);

		addClass(el, this.CSS_SORTED);
		// not sorted, so use default
		if (this.CSS_SORTED_ASC == el.getAttribute(this.ATTR_DEFAULT_SORT_DIR)) {
			addClass(el, this.CSS_SORTED_ASC);
		}
		else {
			addClass(el, this.CSS_SORTED_DESC);
			this.rows.reverse();
		}

	}

	this.lastSort = el.cellIndex;
	this._redrawTable();
};

_SortableTable.prototype._sortRows = function(el) {
	var sortValue;
	if ("true" == el.getAttribute(this.ATTR_USE_SORT_FIELD)) {
		sortValue = this.ATTR_SORT_VALUE;
	}

	var cellIndex = el.cellIndex;
	if (el.cellIndex > 0 && this.sortableColHeads[el.cellIndex-1] && this.sortableColHeads[el.cellIndex-1].getAttribute("colSpan")) {
		 cellIndex = el.cellIndex + (this.sortableColHeads[el.cellIndex-1].getAttribute("colSpan") - 1);
	}
	

	function sorter(a,b) {
		if (sortValue) {
			var aa = String(a.cells[cellIndex].getAttribute(sortValue)).toLowerCase();
			var bb = String(b.cells[cellIndex].getAttribute(sortValue)).toLowerCase();
		}
		else {
			var aa = String(a.cells[cellIndex].innerHTML).toLowerCase();
			var bb = String(b.cells[cellIndex].innerHTML).toLowerCase();
		}

		var numAA = parseFloat(aa);
		var numBB = parseFloat(bb);

		if (!isNaN(numAA) && !isNaN(numBB)) {
			return numAA - numBB;
		}
		else if (aa>bb) {
			return 1;
		}
		else if (aa<bb) {
			return -1;
		}

		return 0;
	}

	this.rows.sort(sorter);
};

_SortableTable.prototype._redrawTable = function() {
	Element.removeChildNodes(this.tbody);
	for (var i=0; i<this.rows.length; i++) {
		Element.addChild(this.tbody, this.rows[i]);
	}
	if(this.tbody.WSOD_clone) {
		Element.removeChildNodes(this.tbody.WSOD_clone);
		for (var i=0; i<this.rows.length; i++) {
			Element.addChild(this.tbody.WSOD_clone, this.rows[i].WSOD_clone);
		}
	}
};

SortableTable.sortables = [];
SortableTable.initAllSortableTables = function(TableConstructor, tables) {
	TableConstructor = TableConstructor || SortableTable;
	tables = tables || Element.parseSelector("table.sortable");

	for (var i=0; i<tables.length; i++) {
		
		if (this.sortables[i]) {
			//already exists, reuse it
			var thead = Element.parseSelector("thead", tables[i], "first");
			var tbody = Element.parseSelector("tbody", tables[i], "first");
			this.sortables[i].init(thead, tbody);
		}
		else {
			this.sortables.push(new TableConstructor(tables[i]));
		}
	}
	return this.sortables;

};

GroupedSortableTable = function(table, rowOfHead) {
	rowOfHead = rowOfHead || 0;
	GroupedSortableTable.Super(this, null, [
		Element.parseSelector("thead", table)[rowOfHead], 
		Element.parseSelector("tbody", table, "first")
	]);
};
GroupedSortableTable.Extend(_SortableTable);

GroupedSortableTable.prototype.init = function(table, rowOfHead) {
	GroupedSortableTable.Super(this, "init", arguments);

	this.tbodys = Element.parseSelector("tbody", this.table);
};

GroupedSortableTable.prototype._sort = function(e, el) {
	var dir = -1;
	if (Element.hasClass(el, this.CSS_SORTED)) {
		if (Element.hasClass(el, this.CSS_SORTED_ASC)) {
			Element.replaceClass(el, this.CSS_SORTED_ASC, this.CSS_SORTED_DESC);
		} else {
			Element.replaceClass(el, this.CSS_SORTED_DESC, this.CSS_SORTED_ASC);
			dir = 1;
		}
	}
	else {
		if (this.colHeads[this.lastSort]) {
			Element.removeClass(this.colHeads[this.lastSort], this.CSS_SORTED);
		}

		Element.addClass(el, this.CSS_SORTED);

		if (this.CSS_SORTED_ASC == el.getAttribute(this.ATTR_DEFAULT_SORT_DIR)) {
			Element.addClass(el, this.CSS_SORTED_ASC);
			dir = 1;
		}
		else {
			Element.addClass(el, this.CSS_SORTED_DESC);
		}
	}

	this.lastSort = el.cellIndex;
	this._sortRows(el, dir);
};

GroupedSortableTable.prototype._sortRows = function(el, dir) {
	var sortValue;
	var sortFunction = this._sorter;

	if ("true" == el.getAttribute(this.ATTR_USE_SORT_FIELD)) {
		sortValue = this.ATTR_SORT_VALUE;
	}

	var groupSortRows = [];
	for (var i=0; i<this.tbodys.length; i++) {
		var rows = Element.parseSelector("tr", this.tbodys[i]);
		if (rows.length) {

			function sorter(a, b) {
				return sortFunction(rows, el, sortValue, dir, true, a, b);
			};
			rows = rows.sort(sorter);


			Element.removeChildNodes(this.tbodys[i]);
			for (var j=0; j<rows.length; j++) {
				Element.addChild(this.tbodys[i], rows[j]);
			}
			groupSortRows.push(rows[0]);
		}
	}

	function sortGroups(a, b) {
		return sortFunction(null, el, sortValue, dir, false, a, b);
	};
	groupSortRows = groupSortRows.sort(sortGroups);

	for (var i=0; i<groupSortRows.length; i++) {
		var tbody = groupSortRows[i].parentNode;
		Element.remove(tbody);
		Element.addChild(this.table, tbody);
	}

};

GroupedSortableTable.prototype._sorter = function(rows, el, sortValue, dir, preserveFirst, a, b) {
	if (preserveFirst) {
		if (rows[0] == a) {
			return -1;
		}
		else if (rows[0] == b) {
			return 1;
		}
	}

	if (sortValue) {
		var aa = String(a.cells[el.cellIndex].getAttribute(sortValue)).toLowerCase();
		var bb = String(b.cells[el.cellIndex].getAttribute(sortValue)).toLowerCase();
	}
	else {
		var aa = String(a.cells[el.cellIndex].innerHTML).toLowerCase();
		var bb = String(b.cells[el.cellIndex].innerHTML).toLowerCase();
	}

	var numAA = parseFloat(aa);
	var numBB = parseFloat(bb);

	if (!isNaN(numAA) && !isNaN(numBB)) {
		return (numAA - numBB) * dir;
	}
	else if (aa>bb) {
		return 1 * dir;
	}
	else if (aa<bb) {
		return -1 * dir;
	}

	return 0;
};

GroupedSortableTable.prototype._redrawTable = function() {
};

/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/FormSerializerLite.js
*/
function FormSerializerLite ()
{
}

FormSerializerLite.prototype.serialize = function (form)
{
    var s = new Serializer();
    var formData = new Object();
    var elements = form.getElementsByTagName('*');

    for( var i = 0; i < elements.length; i++ )
    {
        if(elements[i] && !elements[i].disabled && elements[i].name)
        {
            var key = elements[i].name, value = this.getValue(elements[i]);
            if( value != undefined )
            {
				if (formData[key]) {
					if (formData[key].constructor != Array) {
						formData[key] = [formData[key]];
					};
					formData[key].push(value);
				} else {
					formData[key] = value;
				};
            }
        }
    }

    return s.serialize(formData);
}

FormSerializerLite.prototype.getValue = function (element)
{
	element = Element.get(element);
	var method = element.tagName.toLowerCase();
	return this.Serializers[method](element);
}

FormSerializerLite.prototype.Serializers = function() {};

FormSerializerLite.prototype.Serializers.input = function(element) {
	switch (element.type.toLowerCase()) {
		case 'checkbox':
		case 'radio':
			return this.inputSelector(element);
		default:
			return this.textarea(element);
	};
};

FormSerializerLite.prototype.Serializers.inputSelector = function(element) {
	return element.checked ? element.value : null;
}

FormSerializerLite.prototype.Serializers.textarea = function(element) {
	return element.value;
}

FormSerializerLite.prototype.Serializers.select = function(element) {
	return this[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element);
}

FormSerializerLite.prototype.Serializers.selectOne = function(element)	{
	var index = element.selectedIndex;
	return index >= 0 ? this.optionValue(element.options[index]) : null;
}

FormSerializerLite.prototype.Serializers.selectMany = function(element) {
	var values, length = element.length;
	if (!length) {
		return null;
	};

	for (var i = 0, values = []; i < length; i++) {
		var opt = element.options[i];
		if (opt.selected) {
			values.push(this.optionValue(opt));
		};
	};
	return values;
};

FormSerializerLite.prototype.Serializers.optionValue = function(opt) {
	//return opt.hasAttribute('value') ? opt.value : opt.text;
	// IE doesn't support el.hasAttribute
	return opt.value;
};


/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/FeatureMessage.js
*/
var FeatureMessage = function(container) {
	if (container) {
		this.init(container);
	}
};

FeatureMessage.initAll = function() {
	var messages = Element.parseSelector("." + this.prototype.CSS_CONTAINER, Element.get("wsod"));
	var featureMessages = [];
	for (var i=0; i<messages.length; i++) {
		featureMessages.push(new FeatureMessage(messages[i]));
	}
	return featureMessages;
}

FeatureMessage.prototype.CSS_CONTAINER = "featureMessage";
FeatureMessage.prototype.CSS_HIDDEN = "wsodHidden";
FeatureMessage.prototype.ATTR_MSG_ID = "messageid";

FeatureMessage.prototype.URL_FOR_CLOSED_MESSAGE = '/ft/resources/buffer/markMessageAsClosed.asp';

FeatureMessage.prototype.setURL = function(url) {
	this.URL_FOR_CLOSED_MESSAGE	= url;
}

FeatureMessage.prototype.init = function(container) {
	this.elContainer = container;
	
	var elCloseIcon = Element.parseSelector(".icon-delete-close", this.elContainer, "first");
	this.getCloseEvent().addElement(elCloseIcon);
}

FeatureMessage.prototype.getCloseEvent = function() {
	var close = Events.add(null, "click", this.close, this);
	this.getCloseEvent = function() {
		return close;
	};
	return this.getCloseEvent();
};

FeatureMessage.prototype.getEventManager = function() {
	var em = new EventManager();
	this.getEventManager = function() {
		return em;
	}
	return this.getEventManager();
};

FeatureMessage.prototype.getFader = function() {
	var f = new Fader();
	this.getFader = function() {
		return f;
	}
	return this.getFader();
};

FeatureMessage.prototype.onClose = function() {
	var e = this.getEventManager().add("closeFeatureMessage");
	this.onClose = function() {
		return e;
	};
	return this.onClose();
};

FeatureMessage.prototype.close = function(e, el) {
	var msgId = this.elContainer.getAttribute(this.ATTR_MSG_ID);
	
	e.cancel();
	el.blur();
	
	this.getFader().fadeOut(this.elContainer, true);

	if (msgId) {
		console.log(msgId);

		new ContentBuffer().load({
			url:		this.URL_FOR_CLOSED_MESSAGE,
			method:		"get",
			data:		{
				msgId: msgId
			}
		});
	}
	
	this.onClose().fire();
};

/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/loadingOverlay.js
*/
var LoadingOverlay = function(parentEl){
	/*the parentEl must have position:relative in order for this to work*/
	this.parentEl = parentEl;
}

LoadingOverlay.prototype.CSS_LOADING = "showLoadingOverlay";
LoadingOverlay.prototype.CSS_HIDDEN = "wsodHidden";

LoadingOverlay.prototype.createLoadingContainer = function(){
	var parentHeight = Element.getSize(this.parentEl).height;
	
	var loadingContainer = 	Element.create("div", {className:[this.CSS_LOADING,this.CSS_HIDDEN].join(" "), "style":"height: "+parentHeight+"px"}, [], this.parentEl);
	return loadingContainer;
}

LoadingOverlay.prototype.getLoadingContainer = function(){
	var loadingContainer = this.createLoadingContainer();
	
	this.getLoadingContainer = function(){
		if(null == Element.parseSelector("div." + this.CSS_LOADING, this.parentEl, "first")){
			this.getLoadingContainer = this.createLoadingContainer;
		}
		return loadingContainer;
	}

	return this.getLoadingContainer();
}

LoadingOverlay.prototype.showLoading = function(){
	Element.removeClass(this.getLoadingContainer(), this.CSS_HIDDEN);
}

LoadingOverlay.prototype.hideLoading = function(){
	Element.addClass(this.getLoadingContainer(), this.CSS_HIDDEN);

}